JUC之condition学习笔记

本文深入解析了Condition机制,包括Condition接口的实现类ConditionObject及其在Java并发编程中的作用。详细介绍了Condition对象如何通过FIFO队列实现线程的等待与唤醒,以及与AQS中的CLH同步队列的交互过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Condition为一个接口,其下仅有一个实现类ConditionObject,由于Condition的操作需要获取相关的锁,而AQS则是同步锁的实现基础,所以ConditionObject则定义为AQS的内部类。

public class ConditionObject implements Condition, java.io.Serializable {
}


2.每个Condition对象都包含着一个FIFO队列,该队列是Condition对象通知/等待功能的关键。在队列中每一个节点都包含着一个线程引用,该线程就是在该Condition对象上等待的线程。

public class ConditionObject implements Condition, java.io.Serializable {
    private static final long serialVersionUID = 1173984872572414699L;

    //头节点
    private transient Node firstWaiter;
    //尾节点
    private transient Node lastWaiter;

    public ConditionObject() {
    }
    /** 省略方法 **/
}

3.调用Condition的await()方法会使当前线程进入等待状态,同时会加入到Condition等待队列同时释放锁。释放锁的时候会将Node从同步CLH队列中移除,并唤醒后续节点。然后检测此节点的线程是否在同步队列上,如果不在,则说明该线程还不具备竞争锁的资格。此时会阻塞当前线程。当从await()方法返回时,当前线程一定是获取了Condition相关连的锁。
4.调用Condition的signal()方法,将会唤醒在等待队列中等待最长时间的节点(条件队列里的首节点),在唤醒节点前,会将节点移到CLH同步队列的尾部。
5.Condition的原理主要涉及到两个队列,一个是AQS中的CLH同步队列,一个是ConditionObject中的等待队列。CLH同步队列是双向队列,ConditionObject中的等待队列为一个单向队列。
CLH同步队列如图。


Condition中的等待队列如图。


6.CLH同步队列全程为Craig, Landin, and Hagersten队列。
7.condition使用示例。

public class ConditionTest {
    private LinkedList<String> buffer;    //容器
    private int maxSize ;           //容器最大
    private Lock lock;
    private Condition fullCondition;
    private Condition notFullCondition;

    ConditionTest(int maxSize){
        this.maxSize = maxSize;
        buffer = new LinkedList<String>();
        lock = new ReentrantLock();
        fullCondition = lock.newCondition();
        notFullCondition = lock.newCondition();
    }

    public void set(String string) throws InterruptedException {
        lock.lock();    //获取锁
        try {
            while (maxSize == buffer.size()){
                notFullCondition.await();       //满了,添加的线程进入等待状态
            }

            buffer.add(string);
            fullCondition.signal();
        } finally {
            lock.unlock();      //记得释放锁
        }
    }

    public String get() throws InterruptedException {
        String string;
        lock.lock();
        try {
            while (buffer.size() == 0){
                fullCondition.await();
            }
            string = buffer.poll();
            notFullCondition.signal();
        } finally {
            lock.unlock();
        }
        return string;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值