admin管理员组

文章数量:1599541

1、Condition定义

Condition是一个接口,定义在juc中(java.util.concurrent.locks.Condition),它的主要功能类似于wait()/notify(),但是Condition其实现比wait()/notify()使用更加灵活,简洁、适用场景更加丰富。

2、Condition之于Lock与wait()/notify()之于synchronized

2.1 wait()/notify()之于synchronized

java.lang.Object中定义了一组监视器方法,例如wait()、wait(long timeout)、wait(long timeout, int nanos)、notify()、notifyAll()而object是任何对象的超类,所以任意java对象都拥有这组监视器方法。这些方法再配合上synchronized同步关键字,我们就可以实现等待/通知机制。

2.2 Condition之于Lock

Condition接口中提供了await()、await(long time, TimeUnit unit)、signal()、signalAll()等方法的定义,这些方法的实现配合上Lock也可实现等待/通知机制。

2.3 Object监视器方法与Condition接口两者简要对比

注意:在Condition对象中,与wait()、notify()、和notifyAll()对应的方法分别是await()、signal()、signalAll()方法。Condition对Object进行了扩展(隐藏关系),所有Condition包含wait()和notify()方法。

对比项 Object监视器方法 Condition
前置条件 获取锁 获取锁
调用方式 object.wait() Lock.newCondition()获取Conditon对象,condition.await()
等待队列 一个 多个
超时等待 支持 支持
等待至某个具体时间 不支持 支持
不响应中断 不支持 支持
唤醒一个线程 支持 支持
唤醒全部线程 支持 支持

对于上述对比中最重要的区别在于:

  1. Condition提供更加丰富的wait()机制,例如基于指定时间的限时等待
  2. 对于每个Lock,可以存在任意数量的Condition对象。

3、Condition接口定义与使用案例

3.1 Condition的接口定义

Condition接口中定义的方法如下,具体方法定义的含义请看方法上的注释

public interface Condition {
   

    /**
     * 当前线程进入等待状态,直到被通知(signal)或者中断
     * 返回的前提:
     * 1、其他线程调用该Condition的signal()或者signalAll()方法&&获取到锁
     * 2、其他线程中断了该线程
     */
    void await() throws InterruptedException;

    /**
     * 等待直至被通知,不响应中断
     */
    void awaitUninterruptibly();

    /**
     * 等待通知、中断或者指定等待时间到则返回
     */
    boolean await(long time, TimeUnit unit) throws InterruptedException;

    /**
     * 等待通知、中断或者规定线程截止日期已经过去则返回
     */
    boolean awaitUntil(Date deadline) throws InterruptedException;

    /**
     * 唤醒一个等待线程,线程返回的前提是该线程获取到与Condition有关的锁
     */
    void signal();

    /**
     * 唤醒所有等待线程,线程返回的前提是该线程获取到与Condition有关的锁
     */
    void signalAll();
}

3.2 Lock接口定义

获取Condition必须通过Lock的newCondition()方法,这个在如下接口定义中可以找到结论。

/**
 * Lock接口中定义了Condition的获取方式
 */
public interface Lock {
   

    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

    void unlock();

    /**
     * 调用 newCondition()方法返回一个Condition
     */
    Condition newCondition();
}
3.3 使用案例

通过Lock和Condition来实现一个有界缓存队列,生产线程的向队列中添加数据,当队列满了的时候put()操作会被阻塞;反之,消费线程不断的从队列中取出数据,当队列为空时,take()操作会被阻塞。

package com.lizba.p6;

import org.omg.CORBA.Object;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

本文标签: 原理Javacondition