Condition
等待/通知机制,在Java中主要有两种方式:
- 一是基于wait/notify方法结合synchronized关键字来实现
- 二是Condition结合Lock来实现
- Condition理解为条件队列
- Condition是在java1.5才出现。它用来替换传统的 wait(), notify()实现线程之间的协作,但是更加强大。
- Condition用 await(), signal, signalAll方法替代wait(), notify()。假如用wait,notify,有三个线程调用一个对象的某个方法,notify只能随机的唤醒一个线程,而不能指定唤醒某个线程,但是用condition就可以唤醒指定的线程
- condition也被用来实现阻塞队列。
- condition是通过lock锁创建出来的,依赖于lock对象,基本代码是 ReentrantLock.newCondition()
- 调用await方法后,将当前线程加入Condition等待队列中。当前线程释放锁。否则别的线程就无法拿到锁而发生死锁。自旋(while)挂起,不断检测节点是否在同步队列中了,如果是则尝试获取锁,否则挂起。当线程被signal方法唤醒,被唤醒的线程将从await()方法中的while循环中退出来,然后调用acquireQueued()方法竞争同步状态。
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void conditionAwait() throws InterruptedException {
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
}
public void conditionSignal() {
lock.lock();
try {
condition.signal();//condition.signalAll();
} finally {
lock.unlock();
}
}
Q - java多线程多消费者-多生产者模式 2condition是否可以使用while而不是if的问题?
A -
1、假设2个消费者2个生产者,试想下面情况 消费者1进入被阻塞生产者1进入 生产完毕并唤醒消费者1 此时消费者2进入,消费者1虽然被唤醒但并没有抢到cpu,消费者2消费完毕唤醒(此时没有生产者被唤醒) 此时如果消费者1能够抢赢生产者2则就会出现空消费的问题,所以需要while再次判断。
2、存在虚假唤醒,所以需要重新循环判断