1.ReentrantLock.unlock()分析
(1)首先尝试释放锁,如果要求释放数等于锁状态数,那么将锁状态位清0,清除锁所有者,返回true;否则返回false;
(2)如果(1)返回的是true,说明锁完全释放。接下来将检查等待队列,并选择一个waitStatus处于等待状态的节点下的线程unpark(恢复),选择的依据是从尾节点开始,选取最靠近头节点的等待节点,同时清理队列中线程被取消的节点;
(3)如果(1)返回false,说明锁只是部分释放,当前线程仍旧持有该锁;
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1java.util.concurrent.locks.ReentrantLock
2 public void unlock() {
3 sync.release(1);
4 }
5
6java.util.concurrent.locks.AbstractQueuedSynchronizer
7public final boolean release(int arg) {
8 if (tryRelease(arg)) {
9 Node h = head;
10 if (h != null && h.waitStatus != 0)
11 unparkSuccessor(h);
12 return true;
13 }
14 return false;
15 }
16
17
18 protected final boolean tryRelease(int releases) {
19 int c = getState() - releases; //重入锁加锁的次数-释放数量
20 if (Thread.currentThread() != getExclusiveOwnerThread()) //判断独占锁是否为当前线程所有
21 throw new IllegalMonitorStateException();
22 boolean free = false;
23 if (c == 0) { //加锁次数=释放数量
24 free = true;
25 setExclusiveOwnerThread(null); //清除锁拥有者标识
26 }
27 setState(c); //设置加锁状态
28 return free;
29 }
30
31
32 /**
33 * Wakes up node's successor, if one exists.
34 *
35 * @param node the node
36 */
37 private void unparkSuccessor(Node node) {
38 /*
39 * Try to clear status in anticipation of signalling. It is
40 * OK if this fails or if status is changed by waiting thread.
41 */
42 compareAndSetWaitStatus(node, Node.SIGNAL, 0); //清除头节点signal状态
43
44 /*
45 * Thread to unpark is held in successor, which is normally
46 * just the next node. But if cancelled or apparently null,
47 * traverse backwards from tail to find the actual
48 * non-cancelled successor.
49 */
50 Node s = node.next;
51 if (s == null || s.waitStatus > 0) { //等待队列唤醒的竞争满足FIFO,本段代码主要是寻找最靠近头节点的,且waitStatus为signal、condition的链表节点
52 s = null;
53 for (Node t = tail; t != null && t != node; t = t.prev)
54 if (t.waitStatus <= 0)
55 s = t;
56 }
57 if (s != null)
58 LockSupport.unpark(s.thread);
59 }
2 public void unlock() {
3 sync.release(1);
4 }
5
6java.util.concurrent.locks.AbstractQueuedSynchronizer
7public final boolean release(int arg) {
8 if (tryRelease(arg)) {
9 Node h = head;
10 if (h != null && h.waitStatus != 0)
11 unparkSuccessor(h);
12 return true;
13 }
14 return false;
15 }
16
17
18 protected final boolean tryRelease(int releases) {
19 int c = getState() - releases; //重入锁加锁的次数-释放数量
20 if (Thread.currentThread() != getExclusiveOwnerThread()) //判断独占锁是否为当前线程所有
21 throw new IllegalMonitorStateException();
22 boolean free = false;
23 if (c == 0) { //加锁次数=释放数量
24 free = true;
25 setExclusiveOwnerThread(null); //清除锁拥有者标识
26 }
27 setState(c); //设置加锁状态
28 return free;
29 }
30
31
32 /**
33 * Wakes up node's successor, if one exists.
34 *
35 * @param node the node
36 */
37 private void unparkSuccessor(Node node) {
38 /*
39 * Try to clear status in anticipation of signalling. It is
40 * OK if this fails or if status is changed by waiting thread.
41 */
42 compareAndSetWaitStatus(node, Node.SIGNAL, 0); //清除头节点signal状态
43
44 /*
45 * Thread to unpark is held in successor, which is normally
46 * just the next node. But if cancelled or apparently null,
47 * traverse backwards from tail to find the actual
48 * non-cancelled successor.
49 */
50 Node s = node.next;
51 if (s == null || s.waitStatus > 0) { //等待队列唤醒的竞争满足FIFO,本段代码主要是寻找最靠近头节点的,且waitStatus为signal、condition的链表节点
52 s = null;
53 for (Node t = tail; t != null && t != node; t = t.prev)
54 if (t.waitStatus <= 0)
55 s = t;
56 }
57 if (s != null)
58 LockSupport.unpark(s.thread);
59 }
相关推荐
第六章 ReentrantLock源码解析2--释放锁unlock()最常用的方式://注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁
主要介绍了ReentrantLock源码之条件锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面我们来一起学习一下吧
第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()最常用的方式://注意:通常情况下,这个会设置成一个类变量,比如说Segemen
近日,阅读jdk并发包源码分析整理笔记。
ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。下面我们来深入了解一下它吧
7、深入理解 AQS 独占锁之 Reentrantlock 源码分析 (1).pdf 8、读写锁ReentrantReadWriteLock&StampLock详解.pdf 9、并发容器 (Map、List、Set) 实战及其原理.pdf 10、阻塞队列BlockingQueue 实战及其原理分析.pdf
什么是公平锁和非公平锁 ...对于公平的排他锁而言,先申请锁的线程会先获取锁,但是对于公平的共享锁而言,先申请锁的线程会先拥有获取锁竞争的权利,其他等待共享锁的线程也会被唤醒,有可能后唤醒的线程先获取锁。
ReentrantLock源码剖析
当然在release()方法中不仅仅只是将state- 1这么简单,- 1之后还需要进行一番处理,如果-1之后的新state = 0,则表示当前锁已经被线程释放
1.1 AQS源码解析 https://blog.csdn.net/qq_34125999/article/details/105343472 1.2 Sync /** * ReentrantLock 基础结构 */ abstract static class Sync extends AbstractQueuedSynchronizer { private static ...
今天小编就为大家分享一篇关于Java源码解析之可重入锁ReentrantLock,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
主要为大家详细介绍了Java并发系列之ReentrantLock源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
前言 鼠年新的工作日开始了,新的一年新的工作学习,第一个工作日给自己定一些要求吧。 想写一个系列【隐匿撕源码】 剖析各种经典...我们来看ReentrantLock的构造方法 有两种 传入boolean值 选择此锁是否是公平锁 默
2.synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。 3.synchronized不可响应中断,一个线程获取不...
ReentrantLock前言ReentrantLock简介Synchronized对比用法源码分析代码结构方法分析SyncNonfairSyncFairSync非公平锁VS公平锁什么是公平非公平ReentrantLockReentrantLock的构造函数lock加锁方法非公平的加锁公平的...
主要为大家详细介绍了Java并发系列之ReentrantLock源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
8. Lock接口 (ReentrantLock 可重入锁) 特性 ReentantLock 继承接口 Lock 并实现了接口中定义的方法, 它是一种可重入锁, 除了能完成 synchronized 所能完成的所有工作外,还提供了诸如可响应中断锁、可轮询锁...
ReentrantLock lock方法注释
演示如何通过 lock 和 unlock 方法来实现线程的同步和互斥。 ReentrantLock 的高级功能: 介绍 ReentrantLock 的高级特性,如条件变量、公平性等。讲解如何使用 ReentrantLock 实现更复杂的线程同步逻辑。 通过这份...
NULL 博文链接:https://patrick002.iteye.com/blog/2170391