【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析
前篇博客LZ已经分析了ReentrantLock的lock()实现过程,我们了解到lock实现机制有公平锁和非公平锁,两者的主要区别在于公平锁要按照CLH队列等待获取锁,而非公平锁无视CLH队列直接获取锁。但是对于unlock()而已,它是不分为公平锁和非公平锁的。
public void unlock() {
sync.release(1);
}
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
release(1),尝试在当前锁的锁定计数(state)值上减1。成功返回true,否则返回false。当然在release()方法中不仅仅只是将state - 1这么简单,- 1之后还需要进行一番处理,如果-1之后的新state = 0 ,则表示当前锁已经被线程释放了,同时会唤醒线程等待队列中的下一个线程,当然该锁不一定就一定会把所有权交给下一个线程,能不能成功就看它是不是亲爹生的了(看运气)。
protected final boolean tryRelease(int releases) {
int c = getState() - releases; //state - 1
//判断是否为当前线程在调用,不是抛出IllegalMonitorStateException异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//c == 0,释放该锁,同时将当前所持有线程设置为null
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
//设置state
setState(c);
return free;
}
在release代码中有一段代码很重要:
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
对于这个LZ在前篇博客已经较为详细的阐述了。不懂或者忘记请再次翻阅:【Java并发编程实战】-----“J.U.C”:ReentrantLock之二lock方法分析
waitStatus!=0表明或者处于CANCEL状态,或者是置SIGNAL表示下一个线程在等待其唤醒。也就是说waitStatus不为零表示它的后继在等待唤醒。
unparkSuccessor()方法:
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
//如果waitStatus < 0 则将当前节点清零
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
//若后续节点为空或已被cancel,则从尾部开始找到队列中第一个waitStatus<=0,即未被cancel的节点
Node s = node.next;
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
}
注:unlock最好放在finally中!!!!!!unlock最好放在finally中!!!!!! unlock最好放在finally中!!!!!! (重要的事说三遍)
参考文献:
【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析的更多相关文章
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...
- 【Java并发编程实战】-----“J.U.C”:Semaphore
信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介
注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 【Java并发编程实战】-----“J.U.C”:CyclicBarrier
在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
- 【Java并发编程实战】—– AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...
- Java并发编程实战 02Java如何解决可见性和有序性问题
摘要 在上一篇文章当中,讲到了CPU缓存导致可见性.线程切换导致了原子性.编译优化导致了有序性问题.那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经 ...
随机推荐
- Java源码之 java.util.concurrent 学习笔记01
准备花点时间看看 java.util.concurrent这个包的源代码,来提高自己对Java的认识,努力~~~ 参阅了@梧留柒的博客!边看源码,边通过前辈的博客学习! 包下的代码结构分类: 1.ja ...
- windows server 2008禁止ping
在cmd命令行中通过ping一个主机名.域名或ip地址可以获取到该机器的ip.操作系统等很多信息,处于安全考虑,很多时候不希望服务器被ping,在windows server 2008 r2可以这样操 ...
- word使用笔记(1)
开始字母的格式也是宋体,只要全选后设置字体为Times New Roman即可,会自动跳过中文 新安的Mathtype字体有点奇怪,在样式里设置了一下,果然自定义为宋体了,改回Times New Ro ...
- input=text数字问题
其实老干部也会犯错,今天朋友在银行卡账号时候要求输入数字,它的正则竟然排除中文.其实正则是很重要的.废话少说.如果禁止中文呢 ime-mode 但是这个方法兼容性并不是很好,首先我们得知道. css ...
- PDA手持终端扫描条码开单打印一体 结合后台电脑系统 数据同步交互解决方案
PDA通过扫描商品条码移动开单,实现便携式办公,伴随式销售,PDA能通过WIFI无线局域网.GPRS互联网直接与主机连接,让公司业务人员能随时随地了解公司产品信息,直接扫描商品条码,进行开单.入库.库 ...
- [转]iOS Safari 中click点击事件失效的解决办法
iOS Safari 中click点击事件失效的解决办法 问题起因: 在微信公众号开发(微站)过程中用jquery的live方法绑定的click事件点击无效(不能执行) 问题描述 当使用委托给一个元素 ...
- java-并发-线程对象
浏览以下内容前,请点击并阅读 声明 每个线程都和类Thread的实例相关,有两种基本的使用Thread对象来创建并发应用的方法: 直接控制线程的创建和管理,每次需要开始一个异步任务使简单地实例化Thr ...
- XV Open Cup named after E.V. Pankratiev. GP of Tatarstan
A. Survival Route 留坑. B. Dispersed parentheses $f[i][j][k]$表示长度为$i$,未匹配的左括号数为$j$,最多的未匹配左括号数为$k$的方案数. ...
- WP8解析XML格式文件
DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式,如果要返回XML格式的话,需要在加上format=xml. 这里举一个简单的解析XML格式的例子(更 ...
- C#获取存储过程返回值和输出参数值的方法
//转自网络,先留个底 1.获取Return返回值 //存储过程 //Create PROCEDURE MYSQL // @a int, // @b int //AS // return @a + @ ...