一.使用
选择性地唤醒线程。
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();
}
}
输出:
awaitA
awaitB
signalA
awaitA--------
二.源码
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);
}