在 synchronized 中可以使用 wait 和 notify 来实现线程在条件不满足时等待,条件满足时被唤醒。
在 ReentrantLock 中使用 Condition 对象来实现 wait 和 notify 对应的功能。
这里将 6.wait 和 notify.md 里的 TaskQueue 使用 ReentrantLock 和 Condition 来实现一遍:
class TaskQueue {private final Lock lock = new ReentrantLock();private final Condition condition = lock.newCondition();private Queue<String> queue = new LinkedList<>();public void addTask(String s) {lock.lock();try {queue.add(s);condition.signalAll(); // singnalAll -> notifyAll} finally {lock.unlock();}}public String getTask() {lock.lock();try {while (queue.isEmpty()) {condition.await(); // await -> wait}return queue.remove();} finally {lock.unlock();}}}
使用 Condition 时,引用的 Condition 对象必须从 Lock 实例的 newCondition() 返回,这样才能获得一个绑定了 Lock 实例的 Condition 实例。
在 Condition 中使用等待和唤醒与 synchronized 的函数差异:
await()->wait(), 会释放当前锁,进入等待状态。single()->notify(), 会唤醒某个等待线程。singleAll()->notifyAll(), 会唤醒所有等待线程。
与 Reentrant 的 tryLock() 类似,await() 可以等待指定时间后,如果没有其他线程通过 single() 和 singleAll() 唤醒,它会自己醒来。
if (condition.await(1, TimeUnit.SECOND)) { // 等待时长为 1 秒// 被其他线程唤醒} else {// 指定时间内没有被其他线程唤醒}
小结
Condition 可以替代 wait 和 notify;Condition 对象必须从 Lock 对象获取。
