不想看代码直接看下面的结论
/**
* Factory
*
* @author guigu
* @QQ 1170258867
* @date 2020/5/17
* @description 生产消费工厂
* wait和notify是对于同个把锁的睡眠和唤醒,如果生产者和消费者是两个类,
* 加一个工厂调用组合这两个类实现同步,不然就用Lock
*/
public class Factory {
private int count = 0;
private final int MAX = 10;
public synchronized void producter() throws InterruptedException {
while (count == MAX){
this.wait(); //this是锁对象的 不是锁类的
}
count++;
System.out.println("生产后为:"+count);
this.notifyAll();
}
public synchronized void consummer() throws InterruptedException {
while (count==0){
this.wait();
}
count--;
System.out.println("消费后为:"+count);
this.notifyAll();
}
public static void main(String[] args) {
Factory factory = new Factory();
for (int i = 0; i < 10; i++) {
new Thread(()->{
while (true){
try {
factory.consummer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
for (int i = 0; i < 2; i++) {
new Thread(()->{
while (true){
try {
factory.producter();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
结论:
考虑两个线程的同样的方法先后获得了锁,然后都调用了wait进入阻塞队列,然后另外一个线程消耗了一个(就是说这时候还差一个就到达上限),这时候,如果是if,那么从阻塞队列取出已经判断过了,直接进行下面生产的代码,这样就会生产两个,如果是while,从阻塞队列取出后while在再次判断,第一个线程判断,没满,执行下面生产的代码,第二个线程判断,这时的值已经达到上限,继续wait。