ReentrantLock总结

简述

ReentrantLock是java中非常重要的一个并发工具,相比于java原生的synchronized有着更好的性能

## 概念速查
ReentrantLock涉及的名称和概念较多,这里做一个简单的归类和解释,具体更为详细的内容,请自行Baidu或Google,这部分用于在阅读文章的时候,快速了解一些名称的概念,如果已经熟悉,请跳过。

快速预览

更强大的功能,玩玩意味着更为复杂的使用,ReentrankLock的使用比起synchronize,多了一个主动释放锁的代码,一个典型的使用示例如下

ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
    // ... method body
}finally {
    lock.unlock();
}

注意unlock的操作一定要置于finally块中,这样才能保证锁一定能释放。

uml图

看完了简单的使用示例,我们来快速的看一遍ReentrankLock的结构,下面是用idea的工具快速生成的uml图,感谢idea,大大提高了我们的工作质量。


ReentrantLock-UML.png

一次性过于深入的讨论,往往会迷失在繁琐的细节中,而难以把握全貌,而细节往往是由全局的目标决定的,所以我们一层一层的谈,不一次性深入最终代码。

由uml图,我们可以看出,ReentrantLock类是一个Lock接口的具体实现,每个ReentrantLock的实例,都持有一个sync对象,且这个sync是final修饰的,这个sync有两种具体的子类,分别是NonfairSync和FairSync,也就是非公平锁和公平锁。

ReentrantLock有两个构造方法,我们可以先看这两个方法,

public ReentrantLock() {
    sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
    sync = (fair)? new FairSync() : new NonfairSync();
}

可以看出,所谓构造函数,其实就是初始化需要使用的sync的类型,默认是非公平锁。参考公平锁与非公平锁

简要的预备知识

CAS

ReentrantLock的核心是对CAS方法的使用,现代的CPU提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet()使用了这些命令,具体请查阅CAS原理分析

wait

第一层解析

加锁部分

ReentrantLock的lock其实就是调用具体的sync的lock方法。
公平锁和非公平锁的加锁是有所不同的
对于公平锁来说如下

final void lock() {
    acquire(1);
}

对于非公平锁来说,是如下的

final void lock() {
  if (compareAndSetState(0, 1))
         setExclusiveOwnerThread(Thread.currentThread()); 
  else        acquire(1);
}

很显然,我们可以看出对于公平锁来说,非公平锁多了一个操作。我们首先来解释一下compareAndSetState方法,这个方法来自于sync继承的AbstractQueuedSynchronizer父类。state为0表示当前锁没有被占用,如果大于0,则表示被持有了,使用compareAndSetState,底层是个CAS方法,如果锁没有被占用,则置为占用状态,并且通过setExclusiveOwnerThread,将当前线程设置为该锁的持有者。

tryAcquire这个方法的作用,java的官方注释上如下写到
Acquires in exclusive mode, ignoring interrupts
大意是"尝试在独占模式下获取,忽略中断"。
截止到目前为止,我们看到的加锁过程的流程图如下,很简单

ReentrantLock第一层.png
acquire的工作

接下来,我们研究一下acquire做的工作

public final void acquire(int arg) {
    if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}

tryAcquire,尝试将锁的状态置为arg,如果成功,则结束function,如果失败,在CHL队列中添加一个新的独占锁的节点,节点如果添加失败,则不做后续处理,如果成功则使用selfInterrupt将当前线程中断。流程图如下

解锁部分

我们跳过acquire具体做了什么,我们直接来看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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容

  • 作者: 一字马胡 转载标志 【2017-11-03】 更新日志 前言 在java中,锁是实现并发的关键组件,多个...
    一字马胡阅读 44,149评论 1 32
  • 前言 上一篇文章《基于CAS操作的Java非阻塞同步机制》 分析了非同步阻塞机制的实现原理,本篇将分析一种以非同步...
    Mars_M阅读 4,798评论 5 9
  • 博客链接:http://www.ideabuffer.cn/2017/03/15/深入理解AbstractQueu...
    闪电是只猫阅读 6,219评论 5 22
  • 孤独 衍生出漠视 漠视 助长了孤独 被抽空的世界 生怕谁闯进来 温暖了你 于是关上门
    尚晓阅读 233评论 1 3
  • 月已悬挂钩上楼台,春风对面吹夜已白。 舟似沉侧畔遥江面,两点雪飘飞奈何来。 情字寒凄切对长晚,思念如海水奔月怀。 ...
    昨夜星辰已泛黄阅读 202评论 0 2