时间: 2020-11-24|29次围观|0 条评论

问题1:重复生产,重复消费

原因:被唤醒的线程没有判断标记就进行了生产或者消费,导致重复的生产与消费。 解决办法:就是被唤醒的线程必须先判断,while循环可以让被唤醒的线程再次进行标记判断。   问题2:唤醒以后出现了死锁 原因:本方线程使用notify()时有可能唤醒本方线程,本方线程循环判断标记之后,再次被wait(),导致所有线程全部进入冻结状态,没有就绪状态的线程存在,出现死锁。   解决方法:使用notifyAll()方法,每次都将线程池中的所有线程全部唤醒,不但唤醒本方,还唤醒了对方,虽然唤醒了本方,但是本方判断标记之后,继续wait(),这样对方线程就可以执行了。

 

package ProConDemo; //创建共享资源 public class Goods { private String name; private int count = 1; private boolean flag; //创建一个生产方法 public synchronized void Sale(String name) { while(flag)//线程只要被唤醒,就必须进行循环判断。 try {wait();} catch (InterruptedException e) {e.printStackTrace();} this.name = name +"----"+count; count++; System.out.println(Thread.currentThread().getName()+"生产了"+this.name); flag = true;//改变标记,让对方线程能够执行 notifyAll();//唤醒所有线程   } //创建一个消费方法 public synchronized void Buy() { while(!flag)//线程只要被唤醒,就必须进行循环判断。 try {wait();} catch (InterruptedException e) {e.printStackTrace();} System.out.println(Thread.currentThread().getName()+"消费了"+this.name); flag = false;//改变标记,让对方线程能够执行 notifyAll();//唤醒所有线程 } } package ProConDemo; //创建线程任务----生产者 public class Pro implements Runnable{ private Goods good;   public Pro(Goods good) { this.good = good; } public void run() { while(true) good.Sale("面包");   }   } package ProConDemo; //创建线程任务----消费者 public class Cou implements Runnable{ private Goods good;   public Cou(Goods good) { this.good = good; }   public void run() { while(true) good.Buy();   }     } package ProConDemo;   public class Demo {   public static void main(String[] args) { // TODO Auto-generated method stub Goods good = new Goods();   Pro pro = new Pro(good); Cou cou = new Cou(good);   Thread t0 = new Thread(pro); Thread t1 = new Thread(pro); Thread t2 = new Thread(cou); Thread t3 = new Thread(cou); t0.start(); t1.start(); t2.start(); t3.start(); }   }

转载于:https://www.cnblogs.com/olddriver123/p/8250829.html

原文链接:https://blog.csdn.net/weixin_30342827/article/details/95773798

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《多生产多消费
   

还没有人抢沙发呢~