并发编程原理与实战(十九)精细并发协同控制接口Condition全面剖析

上一篇我们对ReentrantLock的API进行了详细的分析,相比于synchronized单个条件等待通知,ReentrantLock的多条件支持是核心优势之一,能进行更精细的多线程并发协同控制,而这核心优势依赖于与Condition接口的配合使用。本来就来进一步学习Condition接口的相关API。

认识Condition接口

要用ReentrantLock实现多条件并发协同,必须配合Condition接口使用,Condition接口是用于线程间协调通信的核心工具,下面我们就来分析下Condition接口的的相关API。

代替传统wait()/notify()

/**
 * {@code Condition} factors out the {@code Object} monitor
 * methods ({@link Object#wait() wait}, {@link Object#notify notify}
 * and {@link Object#notifyAll notifyAll}) into distinct objects to
 * give the effect of having multiple wait-sets per object, by
 * combining them with the use of arbitrary {@link Lock} implementations.
 * Where a {@code Lock} replaces the use of {@code synchronized} methods
 * and statements, a {@code Condition} replaces the use of the Object
 * monitor methods.
 */

Condition 将Object的监视器方法,Object#wait() 、Object#notify 和 Object#notifyAll分解为独立对象,通过与任意Lock接口的实现结合, 实现每个对象拥有多个等待集的效果。当Lock接口替代了synchronized方法和语句时,Condition 则替代了 Object 的监视器方法

条件变量

/* <p>Conditions (also known as <em>condition queues</em> or
 * <em>condition variables</em>) provide a means for one thread to
 * suspend execution (to &quot;wait&quot;) until notified by another
 * thread that some state condition may now be true.  Because access
 * to this shared state information occurs in different threads, it
 * must be protected, so a lock of some form is associated with the
 * condition. The key property that waiting for a condition provides
 * is that it <em>atomically</em> releases the associated lock and
 * suspends the current thread, just like {@code Object.wait}.
 */

Conditions(也称为条件队列或 条件变量)提供了一种机制,使一个线程可暂停执行(进入“等待”状态),直到另一线程通知其某些状态条件可能已为真。由于共享状态信息在不同线程中被访问,必须通过某种形式的锁进行保护,因此条件总与锁关联。等待条件的关键特性是:它能原子性地释放关联锁并挂起当前线程,类似Object.wait的行为。

/* <p>A {@code Condition} instance is intrinsically bound to a lock.
* To obtain a {@code Condition} instance for a particular {@link Lock}
* instance use its {@link Lock#newCondition newCondition()} method.
*/

Condition实例本质上绑定到一个锁。为特定 Lock实例获取Condition实例,需使用其 Lock接口的newCondition() 方法。

/* <p>As an example, suppose we have a bounded buffer which supports
 * {@code put} and {@code take} methods.  If a
 * {@code take} is attempted on an empty buffer, then the thread will block
 * until an item becomes available; if a {@code put} is attempted on a
 * full buffer, then the thread will block until a space becomes available.
 * We would like to keep waiting {@code put} threads and {@code take}
 * threads in separate wait-sets so that we can use the optimization of
 * only notifying a single thread at a time when items or spaces become
 * available in the buffer. This can be achieved using two
 * {@link Condition} instances.
 */

经典用法

例如,假设有一个支持put和take方法的有界缓冲区。若在空缓冲区上尝试take,线程将阻塞直至有可用项;若在满缓冲区上尝试put,线程将阻塞直至有可用空间。通过分离put线程和take线程至不同等待集,可在缓冲区有项或空间时仅通知单一线程以优化性能。这可通过两个Condition实例实现:

class BoundedBuffer {
   
   
    final Lock lock = new ReentrantLock();
    final Condition notFull  = lock.newCondition(); 
    final Condition notEmpty = lock.newCondition(); 
 
    final Object[] items = new Object[100];
    int putptr, t
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帧栈

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值