posts - 28,  comments - 15,  trackbacks - 0
前面一节中,我们分析了ReentrantLock.lock()方法,接下来我们接着分析ReentrantLock.unlock()方法。

1.ReentrantLock.unlock()分析

(1)首先尝试释放锁,如果要求释放数等于锁状态数,那么将锁状态位清0,清除锁所有者,返回true;否则返回false;
(2)如果(1)返回的是true,说明锁完全释放。接下来将检查等待队列,并选择一个waitStatus处于等待状态的节点下的线程unpark(恢复),选择的依据是从尾节点开始,选取最靠近头节点的等待节点,同时清理队列中线程被取消的节点;
(3)如果(1)返回false,说明锁只是部分释放,当前线程仍旧持有该锁;

 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    }


posted on 2011-08-19 15:24 zhangxl 阅读(1842) 评论(0)  编辑  收藏 所属分类: java 并发

只有注册用户登录后才能发表评论。


网站导航:
 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(1)

随笔分类(17)

随笔档案(28)

文章分类(30)

文章档案(30)

相册

收藏夹(2)

hibernate

java基础

mysql

xml

关注

压力测试

算法

最新随笔

搜索

  •  

积分与排名

  • 积分 - 95542
  • 排名 - 602

最新评论

阅读排行榜

评论排行榜