述
在线程运行过程中,需要等待某个条件的时候,就可以用 Condition
,调用它的 await()
方法,进入阻塞状态等待,当另一个线程去执行对应的条件,直到这个条件达成的时候就去执行它的 signal()
方法,这时候JVM会从被阻塞的线程中找等待该条件的线程,然后唤醒,继续执行
常用方法
await()
: 调用后进入阻塞状态signalAll()
: 唤起全部的正在等待的线程signal()
: 公平的,唤起一个等待时间最长的线程
使用案例
代码如下:
@Slf4j
public class ConditionTest {private ReentrantLock lock = new ReentrantLock();private Condition condition = lock.newCondition();void doSomeThing1() {lock.lock();try {log.info("条件不满足,等待...");condition.await();log.info("条件满足,继续执行...");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}void doSomeThing2(){lock.lock();try {log.info("准备工作完成,唤醒其他的线程...");condition.signal();} finally {lock.unlock();}}public static void main(String[] args) {ConditionTest conditionTest = new ConditionTest();new Thread(conditionTest::doSomeThing1).start();new Thread(conditionTest::doSomeThing2).start();}
}
控制台运行输出如下:
11:34:34.581 [Thread-0] INFO com.learning.java.cooperation.ConditionTest - 条件不满足,等待...
11:34:34.613 [Thread-1] INFO com.learning.java.cooperation.ConditionTest - 准备工作完成,唤醒其他的线程...
11:34:34.613 [Thread-0] INFO com.learning.java.cooperation.ConditionTest - 条件满足,继续执行...
注意点
- 实际上,如果说
Lock
用来代替synchronized
, 那么Condition
就是用来代替相对应的Object.wait/notify
的,所以在用法和性质上,几乎都一样 await()
方法会自动释放持有的Lock锁,和Object.wait
一样,不需要自己手动先释放锁- 调用
await()
的时候,必须先持有锁,否则会抛异常