what
任意一个Java对象,都拥有一组监视器方法,这些方法定义在java.lang.Object上,主要包括wait()、wait(long timeout)、notify()、notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,
where
Condition接口的实现类ConditionObject是同步器AQS的内部类,因为Condition的操作需要获取相关联的锁,所以作为同步器的内部类也比较合理。
why
Conditon相对于Object Monitor来说,功能更加全面一些。我们可以来看下对比:
对比项 | Object Monitor Methods | Condition |
---|---|---|
前置条件 | 获取到对象的锁 | 调用Lock.lock()方法获取锁,然后调用Lock.newCondition()方法新建Condition对象 |
调用方式 | 通过object对象调用或者直接调用:object.wait()或者直接wait() | 通过condition对象调用:condition.await() |
等待队列个数 | 一个 | 一个condition对象对应一个等待队列,condition对象可重复新建 |
当前线程释放锁并进入等待状态 | 支持,wait() | 支持,await() |
当前线程释放锁并进入等待状态,在等待状态中不响应中断 | 不支持 | 支持,awaitUninterruptibly() |
当前线程释放锁并进入超时等待状态 | 支持,wait(long timeout) | 支持,awaitNanos(long nanosTimeout) |
当前线程释放锁并进入等待状态到将来的某个时间 | 不支持 | 支持,awaitUntil(Date deadline) |
唤醒等待队列中的一个线程 | 支持,notify(),唤醒哪个线程需要看操作系统对多线程管理的实现 | 支持,signal(),唤醒等待队列中的首节点 |
唤醒等待队列中的全部线程 | 支持,notifyAll() | 支持,signalAll() |
API
condition的主要入口方法以及描述
方法名称 | 描述 |
---|---|
void await() throws InterruptedException | 当前线程进入等待状态直到被通知或者中断 当前线程将进入运行状态并从await()方法返回的情况有两种: 1.其他线程调用该Condition的signal()或者signalAll()方法,而当前线程被选中唤醒 2.其他线程通过调用interrupt()方法中断当前线程 如果当前等待线程从await()方法返回,那么表明该线程已经获取到了Condition对象所对应的锁 |
void awaitUninterruptibly() | 当前线程进入等待状态直到被通知,从方法名称上可以看出该方法对中断不敏感 |
long awaitNanos(long nanosTimeout) throws InterruptedException | 当前线程进入等待状态直到被通知、中断或者超时。返回值表示剩余的时间,如果在nanosTimeout纳秒之前被唤醒,那么返回值就是nanosTimeout - 实际耗时,如果返回值是0或者负数,那么可以认定是超时了 |
boolean awaitUntil(Date dateline) throws InterruptedException | 当前线程进入等待状态直到被通知、中断或者到某个时间。如果没有到指定时间就被通知,方法返回true,否则,表示到了指定时间,方法返回false |
void signal() | 唤醒当前condition对象等待队列中的首节点,该线程从等待方法返回前必须获得与Condition相关联的锁 |
void signalAll() | 唤醒当前condition对象等待队列中的所有节点,能够从等待方法返回的线程必须获得与Condition相关联的锁 |
源码
1.等待队列
每个Condition对象都包含着一个队列,我们称之为等待队列,该