传统生产者消费者问题、防止虚假唤醒

传统生产者消费者问题、防止虚假唤醒

package JUC;
/**   
 * Copyright © 2021 eSunny Info. Tech Ltd. All rights reserved.
 * 
 * 功能描述:生产者
 * 操作同一个变量 通知等待唤醒
 * Provider num + 1
 * Consumer num - 1
 */
public class ProviderConsumer {
	
	public static void main(String[] args) {
		Data data = new Data();
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					data.increment();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		},"A") .start();
		
		new Thread(()->{
			for (int i = 0; i < 10; i++) {
				try {
					data.decrement();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		},"B") .start();
	}
}

class Data{//数字 资源类
	
	private int number = 0;
	
	// +1
	public synchronized void increment() throws InterruptedException {
		if (number!=0) {
			//等待减少
			this.wait();
		}
		number++;
		System.out.println(Thread.currentThread().getName() + "票数加 +"+ number);
		
		//通知
		this.notifyAll();
	}
	
	// -1
	public synchronized void decrement() throws InterruptedException {
		if (number==0) {
			//等待增加
			this.wait();
		}
		number--;
		System.out.println(Thread.currentThread().getName() + "票数减 -"+ number);
		
		//通知
		this.notifyAll();
	}
	
}

传统生产者消费者问题、防止虚假唤醒
2个线程看起来没有问题,但是当打开4个线程呢?

防止虚假唤醒

线程也可以唤醒,而不会被通知,中断或超时,即所谓的虚假唤醒。虽然实践中很少发生,但应用程序必须通过测试应该使线程被唤醒的条件来防范,并且如果条件不满足则继续等待。换句话讲,等待应该总是出现在循环中:
将if 修改成while循环判断
传统生产者消费者问题、防止虚假唤醒

上一篇:Semaphore 信号量


下一篇:线程休眠 模拟倒计时