java condition_(原创)Java的ReentrantLock(可重入锁)下的Condition
先来看一下这个Condition的使用场景,在LinkedBlockingQueue(链表的阻塞队列)类中包含如下的定义,通过使用lock.newCondition()方法,可以获得一个Condition对象,说明Condition与ReentrantLock有着重要的关联关系。
Condition对象创建
通常它们的使用方式是如下这样,注意线程1的condition.await()和线程2的condition.signal()方法,后面重点讲解这两个方法。
例子
Condition类是AQS(AbstractQueuedSynchronizer,抽象的队列同步器)的内部类,我们重点来看下这个线程1的condition.await()方法,对里面的几个重要方法进行重点的说明。
await()方法
Node node = addConditionWaiter();//将当前线程包装成Node,然后放入条件等待队列中,注意这个队列和//外面的ReentrantLock的同步等待队列是两个不同的队列,在唤醒时(也就是调用condition.signal()),会把//这个线程先从条件等待队列中移除,然后转移到ReentrantLock的同步等待队列里面去,然后在同步等待队列//中获取锁以后,才能真正的被执行int savedState = fullyRelease(node);//在将当前线程放入到条件等待队列中以后,这个方法会把当前线程//所持有的锁释放掉,这个时候ReentrantLock同步等待队列中的某一个线程会获得锁,然后被激活int interruptMode = 0;while (!isOnSyncQueue(node)) {//判断当前线程如果不存在于ReentrantLock同步队列中,则将当前线程//中断挂起,如果这个线程存在于ReentrantLock同步队列中,那么它已经被中断挂起,则不需要再次中断挂起 LockSupport.park(this);
总结来说就是,将当前线程封装成Node,然后加入到条件等待队列中,释放线程持有的锁,然后将此线程中断挂起。
接下来我们重点来看下线程2的condition.signal()方法,对里面的几个重要方法进行重点的说明。
signal()方法
if (!isHeldExclusively())//判断此线程是不是ReentrantLock锁的独占线程,如果不是则抛出异常,换言之//只有是ReentrantLock锁的独占线程,才能进行唤醒操作,也就是说在执行condition.await()//和condition.signal()方法时,线程必须拿到ReentrantLock锁才可以进行,这也就是Condition //与ReentrantLock有着必要的关联关系 throw new IllegalMonitorStateException(); Node first = firstWaiter;//拿到条件等待线程的第一个Node if (first != null) doSignal(first);//第一个Node不为null时,进行唤醒操作
下面来看下doSignal(first)方法的执行逻辑,重点看下其中的transferForSignal(first)方法。
doSignal()方法
transferForSignal()方法
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))//将Node的节点更新为0,如果更新失败, //则代表此节点已经被取消了,直接返回失败,遍历下一个条件等待队列的节点。 return false;Node p = enq(node);//重点方法,将当前节点由条件等待队列转移到ReentrantLock的同步等待队列的队尾中去 int ws = p.waitStatus;//此时被转移到同步等待队列的Node的waitStatus应该是0, if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))//将此Node节点的waitStatus更新为-1 LockSupport.unpark(node.thread);//此逻辑不会执行,因为线程从条件等待队列只是被转移到了同步 //等待队列,而且是队尾的位置,如果同步等待队列前面有有其他线程,则会优先于它被唤醒。 return true;
在执行了condition.signal()方法后,会将条件等待队列中的线程移除,然后转移到ReentrantLock的同步等待队列中,后面的逻辑就和ReentrantLock(可重入锁)执行同步等待队列中的线程一样了(这个逻辑不清楚可以查看我的此篇文章(原创)Java的ReentrantLock(可重入锁)详解上篇)。
简单总结下,Condition依赖于ReentrantLock,必须拿到ReentrantLock锁以后,才可以进行await()和single()方法,在执行了await()时,会释放持有的ReentrantLock锁,并把自己加入到条件等待队列中去,在执行了single()时,会把线程从条件等待队列转移到ReentrantLock的同步等待队列中去,然后等待被真正的执行。
java condition_(原创)Java的ReentrantLock(可重入锁)下的Condition相关推荐
- 聊聊高并发(二十七)解析java.util.concurrent各个组件(九) 理解ReentrantLock可重入锁
这篇讲讲ReentrantLock可重入锁,JUC里提供的可重入锁是基于AQS实现的阻塞式可重入锁.这篇 聊聊高并发(十六)实现一个简单的可重入锁 模拟了可重入锁的实现.可重入锁的特点是: 1. 是互 ...
- Java并发编程-ReentrantLock可重入锁
目录 1.ReentrantLock可重入锁概述 2.可重入 3.可打断 4.锁超时 5.公平锁 6.条件变量 Condition 1.ReentrantLock可重入锁概述 相对于 synchron ...
- java中多线程reentlock_Java多线程系列——深入重入锁ReentrantLock
简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为"独占锁". ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychr ...
- 6※、线程同步、同步锁、同步代码块的使用、同步锁释放的时机、ReentrantLock可重入锁、公平锁与非公平锁的区别、什么是死锁、线程间的通信(生产者和消费者模式)
线程锁 1.※线程的同步:(要确保对象锁是一致的) 1.未使用同步锁的抢票 2.使用了同步锁的抢票 3.线程-同步代码块的使用 4.同步方法和代码块的区别 5.同步锁释放的时机 练习:多线程生产手机 ...
- 1、Lock接口以及ReentrantLock可重入锁
1.序 文章目录 1.序 2.Lock 接口 3.AbstractQueuedSynchronizer 3.1 双端队列 3.2 state变量 4.ReentrantLock简介以及其非公平锁模式 ...
- ReenTrantLock可重入锁(和synchronized的区别)总结
ReenTrantLock可重入锁(和synchronized的区别)总结 可重入性: 从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也 ...
- 深入剖析基于并发AQS的(独占锁)重入锁(ReetrantLock)及其Condition实现原理
[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/75043422 出自[zejian ...
- 死磕Java并发:J.U.C之重入锁:ReentrantLock
ReentrantLock,可重入锁,是一种递归无阻塞的同步机制.它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大.灵活的锁机制,可以减 ...
- Java ReentrantLock可重入锁的源码深度解析
Java的ReentrantLock的源码实现,包括加锁.解锁的源码,以及公平性.重入性的实现! 文章目录 1 ReentrantLock的概述 1.1 ReentrantLock的API方法 1.2 ...
最新文章
- mysql 几十连接_MySQL挑战:10万连接数
- 冒泡排序的PHP实现 Bubble Sort
- 静态库和共享库之间的区别?
- 在PAT上提交Java代码
- 聊起 BigTable,让你不再胆怯
- spring mvc学习(24):配置maven环境和创建maven项目(建议收藏,超全超详细)
- matlab怎么求hadamard,hadamard matlab
- 解决applet覆盖遮罩层div的问题
- 远哥跟你说 Spring的 classpath 通配符加载配置文件
- deepin/ubantu下 mysql 1698错误解决
- P1359 租用游艇 洛谷
- Nginx负载均衡状态值max_fails和fail_timeout
- log4j2 日期换天后,今天的日志打印到了昨天的日志文件里面,rollover混乱
- 16岁女孩攻陷著名安全企业HBGary
- 第二章:互联网灵魂之TCP/IP(二)
- 直播预告|【芯咖秀▪第六期】MCU热的前因后果以及未来到底如何发展!
- mysql求及格百分率_关于mysql进行名次的排名和计算及格率的分享
- 竞拍系统c语言,asp宝贝儿网络拍卖商城购物系统 v11.0 GBK
- TypeScript保存代码时自动编译并运行
- 记录Android开发中的问题及解决方法
热门文章
- “不一样”的真实渗透测试案例分析
- 渗透新手福利---xss到获取cookie入门级
- 013 Android锁机病毒分析
- CVE-2017-11882漏洞分析
- 3.1.4 内存的连续分配管理方式
- 对象属性操作函数:hasattr(),getattr(),setattr()
- Tomcat在自定义xml文件中配置虚拟目录
- Java 中这些常用关键字,总有那么些被你遗忘的
- Java提升篇:理解String 及 String.intern() 在实际中的应用
- Java集合中HashSet的实现原理