Condition接口详解

一、condition和对象监视器

Condition是对象监视器的替代品,拓展了监视器的语义。

  1. 相同:
    都有一组类似的方法:
对象监视器: Object.wait()、Object.wait(long timeout)、Object.notify()、Object.notifyAll()。
Condition对象: Condition.await()、Condition.awaitNanos(long nanosTimeout)、Condition.signal()、Condition.signalAll()

都需要和锁进行关联:

对象监视器: 需要进入synchronized语句块(进入对象监视器)才能调用对象监视器的方法。
Condition对象:需要和一个Lock绑定。
  1. 不同:
    Condition拓展的语义方法:
awaitUninterruptibly():等待时忽略中断
awaitUntil(Date deadline) throws InterruptedException:等待到特定日期

使用方法:

对象监视器: 进入synchronized语句块(进入对象监视器)后调用Object.wait()。
Condition对象: 需要和一个Lock绑定,并显示的调用lock()获取锁,然后调用 Condition.await()

等待队列数量:

对象监视器: 1个。
Condition对象: 多个。通过多次调用lock.newCondition()返回多个等待队列。

二、Condition接口

  1. 声明
    在这里插入图片描述
  2. 等待方法
    不管是发生中断还是超时都将继续竞争锁,而不是立即返回,只有再次获取锁时才能从等待方法返回(这一点和Object等待方法语义是一致的),根据中断状态抛出异常。
    在这里插入图片描述
  3. 通知方法
    在这里插入图片描述

三、Condition接口使用示例

官方文档里举了一个和ArrayBlockingQueue的功能相似的有界塞队列例子,接下来分析一下

  1. 定义
    在这里插入图片描述
  2. put方法
    在这里插入图片描述
  3. get方法
    在这里插入图片描述
    总结:
    在Condition中,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll(),传统线程的通信方式,Condition都可以实现,这里注意,Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用newCondition()方法。Condition的强大之处在于,对于一个锁,我们可以为多个线程间建立不同的Condition。如果采用Object类中的wait(), notify(), notifyAll()实现的话,当写入数据之后需要唤醒读线程时,不可能通过notify()或notifyAll()明确的指定唤醒读线程,而只能通过notifyAll唤醒所有线程,但是notifyAll无法区分唤醒的线程是读线程,还是写线程。所以,通过Condition能够更加精细的控制多线程的休眠与唤醒。

重点注意一点:condition的使用必须依赖于lock对象,通过lock对象的newCondition()方法初始化一个condition对象。

本文参考

猜你喜欢

转载自blog.csdn.net/cristianoxm/article/details/106575371
今日推荐