ReentrantLock提供Condition来实现和wait notify类似的等待通知功能。 使用condition可以实现有选择的通知,在使用notify/notifyAll()方法进行通知时,被通知的线程是由 JVM 选择的。
lock接口中提供了该方法创建Condition对象
//获取等待通知组件
Condition newCondition();
// ReentrantLock的实现
final ConditionObject newCondition() {
return new ConditionObject();
}
Condition提供以下接口以供实现:
void await() throws InterruptedException
// 当前线程进入等待状态,直到被通知(signal)或者被中断时,当前线程进入运行状态,从await()返回;
void awaitUninterruptibly()
// 当前线程进入等待状态,直到被通知,对中断不做响应;
long awaitNanos(long nanosTimeout) throws InterruptedException
// 在接口1的返回条件基础上增加了超时响应,返回值表示当前剩余的时间,如果在nanosTimeout之前被唤醒,返回值 =
// nanosTimeout - 实际消耗的时间,返回值 <= 0表示超时;
boolean await(long time, TimeUnit unit) throws InterruptedException
// 同样是在接口1的返回条件基础上增加了超时响应,与接口3不同的是:
// 可以自定义超时时间单位; 返回值返回true/false,在time之前被唤醒,返回true,超时返回false。
boolean awaitUntil(Date deadline) throws InterruptedException
// 当前线程进入等待状态直到将来的指定时间被通知,如果没有到指定时间被通知返回true,否则,到达指定时间,返回false;
- void signal()
- // 唤醒一个等待在Condition上的线程;
- void signalAll()
- // 唤醒等待在Condition上所有的线程。
ConditionObject是AQS中的一个内部类,每个Condition对象都包含着一个等待队列,该队列是实现
等待通知的关键。
该等待队列在每个节点上都包含一个线程引用,该线程就是等待在Condition上的线程,如果一个线程调用
condition.awit()那么该线程会释放锁,构造成节点加入等待队列进入等待状态。
该等待队列节点和同步队列节点共用一个Node节点类
因为lock可以多次调用new Condition 所以可以创建多个等待队列,
而Object监视器模型上只能有一个等待队列。
具体实现直接看这篇算了 https://www.jianshu.com/p/be2dc7c878dc