62,615
社区成员
发帖
与我相关
我的任务
分享
class Bread
{
String name = "起司";
int count=0;
boolean flag = false;
}
class Maker implements Runnable
{
Bread s ;
Maker(Bread s)
{
this.s = s;
}
public void run()
{
while(true)
{
synchronized(s)
{
if(!s.flag)
{
s.count++;
System.out.println("面包师傅生产了"+s.name+"........"+s.count);
s.flag = true;
}
}
}
}
}
class Consumer implements Runnable
{
Bread s ;
Consumer(Bread s)
{
this.s = s;
}
public void run()
{
while(true)
{
synchronized(s)
{
if(s.flag)
{
System.out.println("胖子消费了"+s.name+"........"+s.count);
s.count--;
s.flag = false;
}
}
}
}
}
class Test
{
public static void main(String[] args)
{
Bread s = new Bread();
Maker a = new Maker(s);
Consumer b = new Consumer(s);
Thread t = new Thread(a);
Thread t2 = new Thread(b);
t.start();
t2.start();
}
}
class Bread
{
String name = "起司";
int count=0;
boolean flag = false;
}
class Maker implements Runnable
{
Bread s ;
Maker(Bread s)
{
this.s = s;
}
public void run()
{
while(true)
{
if(!s.flag)
{
synchronized(s)
{
s.count++;
System.out.println("面包师傅生产了"+s.name+"........"+s.count);
s.flag = true;
}
}
}
}
}
class Consumer implements Runnable
{
Bread s ;
Consumer(Bread s)
{
this.s = s;
}
public void run()
{
while(true)
{
if(s.flag)
{
synchronized(s)
{
System.out.println("胖子消费了"+s.name+"........"+s.count);
s.count--;
s.flag = false;
}
}
}
}
}
class Test
{
public static void main(String[] args)
{
Bread s = new Bread();
Maker a = new Maker(s);
Consumer b = new Consumer(s);
Thread t = new Thread(a);
Thread t2 = new Thread(b);
t.start();
t2.start();
}
}
这个代码没问题,就是把IF放到synchronized就有问题了。这里出现死锁
正是因为flag不能被线程正确的赋值,所以才需要用wai() 和nofityall()控制,而且楼主的程序还需要检查count 是否大于0。 wait()和notifyall()跟死锁没关系,而是要控制线程之间的互动。
[quote=引用 7 楼 soton_dolphin 的回复:] 你需要用到wait()和notifyall去控制线程用共享的资源。当你的一个线程更新了flag,而另一个线程无法更新的时候,就会卡住了
你需要用wait() 和nofiyall()去控制线程之间的互动
package a;
import java.util.*;
class Bread {
boolean stopFlag = false;
String name = "起司";
int count = 0;
public void make(){
synchronized(this){
// 库存超过10,则不再生产,等待消费者消耗库存
while(count >= 10){
try{
this.wait();
}catch(InterruptedException ex){
}
}
count++;
System.out.println("生产面包,当前库存:" + count);
this.notifyAll();
}
}
public void consume(){
synchronized(this){
// 如果库存为0,则等待生产者生产
while(count <= 0){
try{
this.wait();
}catch(InterruptedException ex){
}
}
count--;
System.out.println("消费者消费面包,当前库存:" + count);
this.notifyAll();
}
}
}
class Maker implements Runnable {
Random rdm = new Random();
Bread s ;
Maker(Bread s) {
this.s = s;
}
public void run() {
while(true) {
try{
Thread.sleep(rdm.nextInt(100));
}catch(Exception ex){
}
s.make();
}
}
}
class Consumer implements Runnable {
Random rdm = new Random();
Bread s ;
Consumer(Bread s) {
this.s = s;
}
public void run() {
while(true) {
try{
Thread.sleep(rdm.nextInt(100));
}catch(Exception ex){
}
s.consume();
}
}
}
class Test {
public static void main(String[] args) {
Bread s = new Bread();
Maker a = new Maker(s);
Consumer b = new Consumer(s);
Thread t = new Thread(a);
Thread t2 = new Thread(b);
t.start();
t2.start();
}
}
你需要用到wait()和notifyall去控制线程用共享的资源。当你的一个线程更新了flag,而另一个线程无法更新的时候,就会卡住了
package a;
class Bread {
String name = "起司";
int count=0;
boolean flag = false;
}
class Maker implements Runnable {
Bread s ;
Maker(Bread s) {
this.s = s;
}
public void run() {
while(true) {
try{
Thread.sleep(10);
}catch(Exception ex){}
if(!s.flag) {
synchronized(s) {
s.count++;
System.out.println("面包师傅生产了"+s.name+"........"+s.count);
s.flag = true;
}
}
}
}
}
class Consumer implements Runnable {
Bread s ;
Consumer(Bread s) {
this.s = s;
}
public void run() {
while(true) {
try{
Thread.sleep(10);
}catch(Exception ex){}
if(s.flag) {
synchronized(s) {
System.out.println("胖子消费了"+s.name+"........"+s.count);
s.count--;
s.flag = false;
}
}
}
}
}
class Test {
public static void main(String[] args) {
Bread s = new Bread();
Maker a = new Maker(s);
Consumer b = new Consumer(s);
Thread t = new Thread(a);
Thread t2 = new Thread(b);
t.start();
t2.start();
}
}
楼主的程序应该不是死锁了,而是其中一个线程进入了死循环,并且没有被打断,导致另一个线程没有执行的机会,可能的情况是:
初始时 s.flag = false
生产者执行 :
判断 !s.flag = true
锁 s
s.count++
打印
s.flag = true
释放锁
消费者:
s.flag = true
锁 s
打印
s.count--
s.flag = false
程序被打断 // 此时还没有释放锁
生产者:
!s.flag = true, 进入if语句块
尝试取得锁失败,等待
消费者
释放锁
while 死循环
进入 if(s.flag) 语句,为 false, 继续 while(true) 语句,进入 if(s.flag) 判断为 false,继续 while(true) ……
由于 while 语句没有被打断,导致生产者线程没有机会被执行,因此看起来象是死锁了
如果在生产者和消费者的程序中者程序中加上休眠语句,让另外一个线程有机会执行,则不会“死锁”flag更新后另外一个线程就可以通过IF()判断语句,虽然这时候没有锁的权限。线程不会自己出来吗?等到头一个线程的Flag语句更新后锁全释放。不就可以继续执行另外一个线程吗?这样理解有没有问题。