条件变量
synchronized 中也有条件变量,就是等待队列 waitSet,当条件不满足时进入 waitSet 等待 ReentrantLock 的条件变量比 synchronized 强大之处在于,它是支持多个条件变量的。
使用要点:
- await 前需要获得锁
- await 执行后,会释放锁,进入 conditionObject 等待
- await 的线程被唤醒(或打断、或超时)重新竞争 lock 锁
- 竞争 lock 锁成功后,从 await 后继续执行
private static ReentrantLock lock = new ReentrantLock();
private static Condition waitCigarette = lock.newCondition();
private static Condition waitBreakfast = lock.newCondition();
private static volatile boolean isCigarette = false;
private static volatile boolean isBreakfast = false;
public static void main(String[] args) {
new Thread(() -> {
lock.lock();
try {
while (!isCigarette) {
try {
waitCigarette.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("等到了他的烟");
}
}finally {
lock.unlock();
}
}, "等烟的线程").start();
new Thread(() -> {
lock.lock();
try {
while (!isBreakfast) {
try {
waitBreakfast.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("等到了他的早饭");
}
}finally {
lock.unlock();
}
}, "早餐线程").start();
Sleep.sleep(1);
sendBreakfast();
Sleep.sleep(1);
sendCigarette();
}
private static void sendCigarette() {
lock.lock();
try {
System.out.println("送烟");
isCigarette = true;
waitCigarette.signal();
}finally {
lock.unlock();
}
}
private static void sendBreakfast() {
lock.lock();
try {
System.out.println("送早饭");
isBreakfast = true;
waitBreakfast.signal();
}finally {
lock.unlock();
}
}
输出
送早饭
等到了他的早饭
送烟
等到了他的烟