一.使用
选择性地唤醒线程。
public class ReentrantLockCondition {private static Lock lock = new ReentrantLock();private static Condition conditionA = lock.newCondition();private static Condition conditionB = lock.newCondition();public static void awaitA() throws InterruptedException {lock.lock();System.out.println("awaitA");conditionA.await();System.out.println("awaitA--------");lock.unlock();}public static void awaitB() throws InterruptedException {lock.lock();System.out.println("awaitB");conditionB.await();System.out.println("awaitB--------");lock.unlock();}public static void signalA() {lock.lock();System.out.println("signalA");conditionA.signalAll();lock.unlock();}public static void signalB() {lock.lock();System.out.println("signalB");conditionB.signalAll();lock.unlock();}public static void main(String[] args) throws InterruptedException {new Thread(() -> {try {awaitA();} catch (InterruptedException e) {e.printStackTrace();}}, "线程1").start();new Thread(() -> {try {awaitB();} catch (InterruptedException e) {e.printStackTrace();}}, "线程2").start();Thread.sleep(1000);signalA();}}输出:awaitAawaitBsignalAawaitA--------
二.源码
1.lock.newCondition
final ConditionObject newCondition() {// AQS的内部类return new ConditionObject();}// 单向的等待队列public class ConditionObject {private transient Node firstWaiter;private transient Node lastWaiter;}class Node {Node nextWaiter;}
2.await
public final void await() throws InterruptedException {// 将当前线程包装成Node,尾插入到等待队列中Node node = addConditionWaiter();// 释放锁,唤醒同步队列中的下一个节点int savedState = fullyRelease(node);int interruptMode = 0;while (!isOnSyncQueue(node)) {// 阻塞LockSupport.park(this);if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)break;}// 尝试获取锁,获取不到锁阻塞if (acquireQueued(node, savedState) && interruptMode != THROW_IE)interruptMode = REINTERRUPT;// 获取到锁}
3.signal,不会释放锁,unlock释放锁
public final void signal() {// 当前线程必须持有锁if (!isHeldExclusively())throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignal(first);}private void doSignal(Node first) {do {// 将头结点从等待队列中移除if ( (firstWaiter = first.nextWaiter) == null)lastWaiter = null;first.nextWaiter = null;} while (!transferForSignal(first) &&(first = firstWaiter) != null);}final boolean transferForSignal(Node node) {//将节点插入同步队列的末尾Node p = enq(node);return true;}
4.signalAll
public final void signalAll() {if (!isHeldExclusively())throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignalAll(first);}// 等待队列的所有节点插入同步队列的末尾private void doSignalAll(Node first) {lastWaiter = firstWaiter = null;do {Node next = first.nextWaiter;first.nextWaiter = null;transferForSignal(first);first = next;} while (first != null);}
