虚假唤醒
当同时有多个生产者消费者线程时notifyAll唤醒后多个wait继续执行 可能会导致数据的不安全
主要是由于唤醒后线程重新取得锁后 会继续执行wait后面的操作 之前的代码不会执行 这个时候其他线程已经修改了判断条件 jdk推荐的解决办法为通过 while循环判断造成wait的等待条件public class ProductAndConsumer { public static void main(String[] args) { Pen pen = new Pen(); Consumer cus = new Consumer(pen); Product pro = new Product(pen); new Thread(pro,"pro1").start(); new Thread(pro,"pro2").start(); new Thread(cus,"cus1").start(); new Thread(cus,"cus2").start(); }}class Pen{ private int count = 10; public synchronized void getCount() { while(count < 10) { System.out.println(Thread.currentThread().getName()+":"+ "缺货"); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+":"+ --count); this.notifyAll(); } public synchronized void setCount() { while(count >= 10) { System.out.println(Thread.currentThread().getName()+":"+ "仓库满了"); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+":"+ ++count); this.notifyAll(); }}class Product implements Runnable{ private Pen pen = null; public Product(Pen pen) { this.pen = pen; } @Override public void run() { for(int i=0;i<2000;i++) { pen.setCount(); } }}class Consumer implements Runnable{ private Pen pen = null; public Consumer(Pen pen) { this.pen = pen; } @Override public void run() { try { Thread.sleep(40); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=0;i<2000;i++) { pen.getCount(); } }}