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源码解析之释放锁unlock() ReentrantLock是一个可重入锁,它提供了一个unlock()方法来释放锁。在本章中,我们将深入探讨unlock()方法的源码,了解其释放锁的步骤和机制。 unlock()方法的主要作用是...
Java并发之ReentrantLock类源码解析 ReentrantLock是Java并发包中的一种同步工具,它可以实现可重入锁的功能。ReentrantLock类的源码分析对理解Java并发机制非常重要。本文将对ReentrantLock类的源码进行详细分析,...
ReentrantLock源码详解--条件锁 ReentrantLock源码详解中最重要的一个部分就是条件锁,条件锁是指在获取锁之后发现当前业务场景自己无法处理,而需要等待某个条件的出现才可以继续处理时使用的一种锁。今天我们来...
Java源码解析之可重入锁ReentrantLock ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLock。它是一个可重入的排他锁,它和synchronized的方法和代码有着相同的行为和语义,但有更多的功能。 ...
在尝试获取锁时,应将代码放入try-finally块中,以确保无论发生什么异常,都能正确释放锁。基本用法如下: ```java Lock lock = new ReentrantLock(); lock.lock(); try { doSomething(); } finally { lock....
本文将深入解析ArrayBlockingQueue的内部实现机制和关键特性。 **1. ArrayBlockingQueue的构造** ArrayBlockingQueue在初始化时需要指定其容量大小,这个容量一旦设定就无法改变。构造函数通常需要传入两个参数:...
#### 二、ReentrantLock源码分析 - **介绍**:`ReentrantLock`是一个可重入的互斥锁,它支持公平和非公平两种锁策略。与`synchronized`相比,它提供了更多的功能和更好的灵活性。 - **核心组件**: - **Sync**:...
使用`lock()`和`unlock()`方法,可以在需要的时候获取和释放锁。 ```java import java.util.concurrent.locks.ReentrantLock; public class VoteCounter { private int count = 0; private final ReentrantLock ...
这种机制是通过锁来实现的,本文将深入探讨如何在编程中实现程序的互斥运行,并提供一个实例源码进行解析。 一、互斥锁的概念 互斥锁(Mutex)是一种同步原语,用于控制对共享资源的访问。当一个线程获得锁后,其他...
- 使用Lock需要手动获取和释放锁,如ReentrantLock的lock()和unlock()方法。 4. **线程通信** - wait()、notify()和notifyAll():在同步块或同步方法中使用,用于线程间的通信。必须在持有对象锁的情况下调用,...