任意一个Java对象都有一级监视器办法,像wait(),notify()等,这些办法须要与synchronized配合应用能够实现期待告诉性能。相似的Condition也提供了相应的办法。
Condition作为一个接口,只定义了一些模板办法,实现都在AbstractQueuedSynchronizer的外部类ConditionObject里。上面是Condition里的办法:
简要阐明
在调用下面的办法之前,须要先获取到Condition关联的锁。
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
当调用await()办法后,以后线程会开释锁并期待,而其它线程调用Condition对象的signal()办法,告诉以后线程后,以后线程获取到锁后会从await()办法返回。
实现剖析
- 期待队列
在conditionObject对象里保护着一个FIFO的期待队列,队列中每个节点都蕴含了一个线程援用,该线程就是在condition对象上期待的线程。
一个condition蕴含一个期待队列,condition领有首节点(firstWaiter)和尾节点(lastWaiter),当线程调用了await()办法后,将会以以后线程结构一个节点退出到队列的尾部。
在Object监视器模式下,一个对象领有一个同步队列和一个期待队列,而Lock同步器领有一个同步队列和多个期待队列。
期待
当调用了await()办法后,会应用以后线程进入期待队列并开释锁,同时线程状态变为期待状态。当从await()返回时,以后线程肯定是获取到了锁。
告诉
当调用了signal()办法后,只有在以后线程获取了锁之后,会唤醒在期待队列中等待时间最长的节点(首节点),在唤醒节点之前,节点会被移到同步队列并应用LockSupport唤醒节点中的线程。
Condition里的signalAll()办法,相当于对期待队列中的每个节点都执行一次signal()办法,将期待队列中所有节点全副移到同步队列中,并唤醒每个节点的线程。
应用场景
应用Condition能够实现期待告诉模式,一些非凡的期待队列等。
源码剖析能够看这篇文章:源码剖析:②ReentrantLock之条件锁Condition
参考文章:《Java并发编程的艺术》