Condition 接口是 JDK 1.5 开始提供的,用来实现线程间的等待与唤醒


Condition 的对象可以通过 Lock 对象的 newCondition() 方法创建


Condition 对象方法的调用必须在 Lock 对象的 lock() 和 unlock() 之间,否则会抛出异常 java.lang.IllegalMonitorStateException


Condition 的 await()、signal()、signalAll() 方法与 Object 的 wait()、notify()、notifyAll() 方法功能类似


Condition 接口的方法包括

//当前线程等待,直到收到唤醒的信号或者被中断
void await() throws InterruptedException;
//当前线程等待,直到收到唤醒的信号,不可被中断
void awaitUninterruptibly();
//当前线程等待,直到收到唤醒的信号 或 被中断 或 指定的等待纳秒数超时
long awaitNanos(long nanosTimeout) throws InterruptedException;
//当前线程等待,直到收到唤醒的信号 或 被中断 或 指定的时间超时
boolean await(long time, TimeUnit unit) throws InterruptedException;
//当前线程等待,直到收到唤醒的信号 或 被中断 或 超过指定时间
boolean awaitUntil(Date deadline) throws InterruptedException;
//唤醒一个等待中的线程
void signal();
//唤醒所有等待中的线程
void signalAll();

 

使用示例:

package constxiong.interview;
import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;
/** * 测试 Lock Condition 的使用 * @author ConstXiong * @date 2019-12-09 11:46:17 */public class TestLockCondition {  public static void main(String[] args) throws InterruptedException {    Lock lock = new ReentrantLock();    Condition condition = lock.newCondition();    for (int i = 0; i < 5; i++) {      new Thread(() -> {        try {          lock.lock();          System.out.println(Thread.currentThread().getName() + " wait for the signal");          condition.await();        } catch (InterruptedException e) {          e.printStackTrace();        } finally {          lock.unlock();        }        System.out.println(Thread.currentThread().getName() + " receive the signal, go on ");      }).start();    } //    休眠5秒    Thread.sleep(5000);    new Thread(() -> {      try {//        lock.lock();        System.out.println("signal all current lock's condition");        condition.signalAll();      } finally {        lock.unlock();      }    }).start();  } }


Condition 的实现

  • Condition 接口的唯一实现类是同步器 AQS 的内部类 ConditionObject

  • 每个 Condition 对象都包含着一个 FIFO 队列,拥有首节点(firstWaiter)和尾节点(lastWaiter)

  • 队列中的每个节点都包含了一个在 Condition 对象上等待的线程引用

  • await() 方法相当于同步队列的首节点(已获取锁)移动到 Condition 的等待队列中

  • signal() 方法将会唤醒在等待队列中的节点,移到同步队列中


更多相关文章

  1. Redis为什么又引入了多线程?作者也逃不过“真香定理”?
  2. 详解第三种创建线程的方式-Callable接口
  3. 聊一聊面试中常问的java阻塞队列
  4. java线程相关面试题(第一版)
  5. Java线程之线程的调度-让步
  6. 栈和队列就是这么简单
  7. 阻塞队列 BlockingQueue

随机推荐

  1. php echo什么意思
  2. 如何下载php开源代码
  3. USDT PHP开发包OmniTool简介
  4. php中什么是魔术引号
  5. php如何设置日期
  6. php之日期时间操作一箩筐
  7. wampserver怎么下载
  8. PHP如何实现短网址
  9. php适合做微服务么
  10. php array_chunk函数怎么用