Java JUC 高级线程之八 Condition 线程通信 解决虚假唤醒

版权声明:尊重原创,码字不易,转载需博主同意。 https://blog.csdn.net/qq_34626097/article/details/88935136

文章目录

引入 多线程虚假唤醒问题的解决的出现问题

Condition

  1. Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用Object.wait 访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,当个Lock可能与多个Condition对象相关联。为了避免兼容性问题,Condition方法的名称与对应的Object版本不同。
  2. 在Condition 对象中,与wait、notify 和 notifyAll 方法对应的是 await、signal 和 signalAll。
  3. Condition 实例实质上被绑定到一个锁上。要为特定Lock实例获得Condition实例,请使用其NewCondition()方法。

代码demo

/*
 *虚假唤醒 
 */
public class TestProductorAndConsumerForLock {
	public static void main(String[] args) {
		
		Clerk clerk = new Clerk();
		
		Productor pro = new Productor(clerk);
		Consumer cus = new Consumer(clerk);
		

		new Thread(pro,"生产者A").start();
		new Thread(pro,"生产者D").start();
		new Thread(cus,"消费者C").start();
		new Thread(cus,"消费者F").start();
	}
}

//销售员
class Clerk{
	
	private int product = 0 ;
	
	private Lock lock = new ReentrantLock();
	private Condition conditioin = lock.newCondition();
	//进货
	public  void get() {
		
		lock.lock();
		try {
			while(product >= 1) {//为了解决虚假唤醒问题,应该总是使用在循环中
				System.out.println("产品已经满了");
				
				try {
					conditioin.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			}
				System.out.println(Thread.currentThread().getName()+ " : " + ++product);
				conditioin.signalAll();
		} finally {
			lock.unlock();
		}
		
	}
	
	//出售
	public void sale() {
		
		lock.lock();
		try {
			while(product <= 0) {
				System.out.println("缺货");
				
				try {
					conditioin.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
				System.out.println(Thread.currentThread().getName() + " : " + --product);
				conditioin.signalAll();
		} finally {
			lock.unlock();
		}
	}
}

//生产者
class Productor implements Runnable{
	private Clerk clerk;

	public Productor(Clerk clerk) {
		super();
		this.clerk = clerk;
	}

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			clerk.get();
		}
	}
	
}

//消费者
class Consumer implements Runnable {
	
	private Clerk clerk;

	public Consumer(Clerk clerk) {
		super();
		this.clerk = clerk;
	}

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			clerk.sale();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_34626097/article/details/88935136