简介
条件变量是什么
条件对象这一概念源自于操作系统,设计它是为了解决等待同步需求,实现线程间协作通信的一种机制。Java其实也已经内置了条件变量,它和监视器锁是绑定在一起的,即Object的wait和notify方法,使用这两个方法就可以实现线程之间的协作
Java中的条件变量直到Java 5才出现,用它来代替传统的Object的wait和notify方法。相比wait和notify,Condition的await和signal方法更加安全和高效,因为Condition是基于AQS实现的,加锁、释放锁的效率更高
条件变量顾名思义就是表示某种条件的变量。不过需要说明的是,条件变量中的条件并没有实际含义,仅仅只是一个标记,条件的含义需要代码来赋予
Condition接口
Condition是一个接口,条件变量都实现了Condition接口。该接口的基本方法是await、signal、signalAll这些
不过Condition依赖于Lock接口,需要借助Lock.newCondition方法来创建条件变量。因此Condition必然是和某个Lock绑定在一起的,这就和await和signal一定会和Object的监视器锁绑定在一起。因此,Java中的条件变量必须配合锁使用,来控制并发程序访问竞争资源的线程安全性
Condition和Java内置的条件变量方法之间的对应关系如下:
- Condition.await 等价于 Object.wait
- Condition.signal 等价于 Object.notify
不多BB了,直接看源码吧~
AQS之条件对象
AQS为条件变量的实现提供了95%以上的功能,Lock接口实现类一般只需要实现一下newCondition方法,就可以直接使用条件变量了,你说方不方便!
AQS实现的方式就是直接提供了Condition的一个实现类——ConditionObject,我接下来就将其称为条件对象(可能不太严谨)。ConditionObject是AQS的内部类,可见性为public
条件对象的结构
每个ConditionObject都维护了一个条件队列,首尾节点分别由firstWaiter、lastWaiter两个域来管理:
/** First node of condition queue. */
private transient Node firstWaiter;
/** Last node of condition queue. */
private transient Node lastWaiter;
每个在条件队列中等待的线程都由Node类来维护,它们之间通过Node类的nextWaiter相连,形成一个单向链表。每个Node的waitStatus都是Node.CONDITION,表明该线程正在某个条件变量的条件队列中等待ing~
条件对象的创建
十分的朴实无华且简单通透,要是所有代码都这么简单,那该有多好啊~
public ConditionObject() { }
正如前面所说,如果基于AQS实现的Lock接口实现类想要使用AQS提供的条件变量,只需要实现newCondition方法即可。而实现newCondition方法一般只需要直接调用ConditionObject的构造方法即可,多么简单!
接下来主要剖析一下ConditionObject是如何实现Condition接口的两大重要功能——条件等待、条件唤醒
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任