`
森林的天空
  • 浏览: 15243 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ReentrantLock源码之二unlock方法解析(锁的释放)

 
阅读更多

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    }

 

分享到:
评论

相关推荐

    第六章 ReentrantLock源码解析2--释放锁unlock()1

    ReentrantLock源码解析之释放锁unlock() ReentrantLock是一个可重入锁,它提供了一个unlock()方法来释放锁。在本章中,我们将深入探讨unlock()方法的源码,了解其释放锁的步骤和机制。 unlock()方法的主要作用是...

    Java并发之ReentrantLock类源码解析

    Java并发之ReentrantLock类源码解析 ReentrantLock是Java并发包中的一种同步工具,它可以实现可重入锁的功能。ReentrantLock类的源码分析对理解Java并发机制非常重要。本文将对ReentrantLock类的源码进行详细分析,...

    ReentrantLock源码详解--条件锁

    ReentrantLock源码详解--条件锁 ReentrantLock源码详解中最重要的一个部分就是条件锁,条件锁是指在获取锁之后发现当前业务场景自己无法处理,而需要等待某个条件的出现才可以继续处理时使用的一种锁。今天我们来...

    Java源码解析之可重入锁ReentrantLock

    Java源码解析之可重入锁ReentrantLock ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLock。它是一个可重入的排他锁,它和synchronized的方法和代码有着相同的行为和语义,但有更多的功能。 ...

    21 更高级的锁—深入解析Lock.pdf

    在尝试获取锁时,应将代码放入try-finally块中,以确保无论发生什么异常,都能正确释放锁。基本用法如下: ```java Lock lock = new ReentrantLock(); lock.lock(); try { doSomething(); } finally { lock....

    ArrayBlockingQueue源码解析-动力节点共

    本文将深入解析ArrayBlockingQueue的内部实现机制和关键特性。 **1. ArrayBlockingQueue的构造** ArrayBlockingQueue在初始化时需要指定其容量大小,这个容量一旦设定就无法改变。构造函数通常需要传入两个参数:...

    多线程面试题及处理方案和详解

    #### 二、ReentrantLock源码分析 - **介绍**:`ReentrantLock`是一个可重入的互斥锁,它支持公平和非公平两种锁策略。与`synchronized`相比,它提供了更多的功能和更好的灵活性。 - **核心组件**: - **Sync**:...

    Java 投票(自动加一)

    使用`lock()`和`unlock()`方法,可以在需要的时候获取和释放锁。 ```java import java.util.concurrent.locks.ReentrantLock; public class VoteCounter { private int count = 0; private final ReentrantLock ...

    如何实现程序互斥运行

    这种机制是通过锁来实现的,本文将深入探讨如何在编程中实现程序的互斥运行,并提供一个实例源码进行解析。 一、互斥锁的概念 互斥锁(Mutex)是一种同步原语,用于控制对共享资源的访问。当一个线程获得锁后,其他...

    java+多线程+同步详解源代码学习

    - 使用Lock需要手动获取和释放锁,如ReentrantLock的lock()和unlock()方法。 4. **线程通信** - wait()、notify()和notifyAll():在同步块或同步方法中使用,用于线程间的通信。必须在持有对象锁的情况下调用,...

Global site tag (gtag.js) - Google Analytics