多线程之condition

多线程之condition

Condition 提供的方法

等待方法:

// 当前线程进入等待状态,如果其他线程调用 condition 的 signal 或者 signalAll 方法并且当前线程获取 Lock 从 await 方法返回,如果在等待状态中被中断会抛出被中断异常
void await() throws InterruptedException

// 当前线程进入等待状态直到被通知,中断或者超时
long awaitNanos(long nanosTimeout)

// 同第二个方法,支持自定义时间单位
boolean await(long time, TimeUnit unit)throws InterruptedException

// 当前线程进入等待状态直到被通知,中断或者到了某个时间
boolean awaitUntil(Date deadline) throws InterruptedException

唤醒方法:

// 唤醒一个等待在 condition 上的线程,将该线程从等待队列中转移到同步队列中,如果在同步队列中能够竞争到 Lock 则可以从等待方法中返回
void signal()

// 与 1 的区别在于能够唤醒所有等待在 condition 上的线程
void signalAll()

Condition 与wait/Notify

  1. wait/notify 方式是响应中断的,当线程处于 Object.wait()的等待状态中,线程中断会抛出中断异常;Condition 有响应中断和不响应中断模式可以选择。
  2. wait/notify 方式一个 synchronized 锁只有一个等待队列;一个 Lock 锁可以根据不同的条件,new 多个 Condition 对象,每个对象包含一个等待队列。

每个 ConditionObject 对象都有一个条件等待队列,用于保存在该 Condition 对象上等待的线程

img

AQS的同步队列和Condition的条件队列

  1. 线程抢锁失败时进入 AQS 同步队列,AQS 同步队列中的线程都是等待着随时准备抢锁的。
  2. 线程因为没有满足某一条件而调用 condition.await()方法之后进入 Condition 条件队列,Condition 条件队列中的线程只能等着,没有获取锁的机会。
  3. 当条件满足后调用 condition.signal()线程被唤醒,那么线程就从 Condition 条件队列移除,进入 AQS 同步队列,被赋予抢锁继续执行的机会。

https://mp.weixin.qq.com/s?__biz=MzAxMjEwMzQ5MA==&mid=2448890475&idx=2&sn=103d3d43f3380e42815189c73dcc76a1&scene=21#wechat_redirect