JUC之ReentrantLock

ReentrantLock是可重入的独占锁,同步通过实现AQS(抽象的队列式同步器,内部定义了一套多线程访问共享资源的的同步框架),锁的竞争依靠CAS和Unsafe 。

ReentrantLock使用:

new一个lock对象,调用lock方法获取到锁,在finally代码块调用unlock方法释放锁,如果不在finally代码块释放,代码发生异常会导致锁未能正常释放,造成死锁。

方法说明:

ReentrantLock主要方法实现于Lock

lock() : 获取锁

lockInterruptibly() : 获取锁,可中断

tryLock() : 尝试获取锁

tryLok(long time , TimeUnit unit) : 尝试获取锁,可设置过期时间

unlock() : 释放锁

newCondition() : 构建条件对象,如synchronized的mutex对象的await和notify等功能

源码说明

ReentrantLock自定义sync集成AQS

ReentrantLock内部提供了公平锁和非公平锁,通过源码可知通过无参构造函数创建对象默认使用公平锁,非公平锁在创建对象传入false即可。

公平锁与非公平锁的公平性主要体现在锁的竞争上

公平锁:线程获取锁的时候需添加到同步队列末尾,等待获取

非公平锁:线程获取锁的时候可以直接跟当前同步队列head节点进行CAS竞争获取锁,获取失败后再添加到同步队列末尾,依次等待获取

锁是如何竞争的?

锁的竞争实际上是对AQS同步框架内state原子变量的获取修改,使用unsafe类的CAS(compareAndSwap)修改成功则表明获取到锁,unsafe和CAS不在此展开讲解。

公平锁和非公平锁取锁过程都实现了AQS的抽象方法tryAcquire方法,传入参数都为1。

公平锁和非公平锁都是先获取AQS框架中的原子变量state,如果是state==0就通过CAS尝试将state从0改为1,setExclusiveOwnerThread是设置当前线程为独占锁拥有者,else代码块我们还可以发现如果当前线程是独占锁拥有者则可以直接获取锁,不需要重复排队获取,将state+acquires即可。从这里我们知道ReentrantLock是可重入的锁,(state-1)的数值就是锁重入的次数。

非公平锁相较于公平锁除了在调用lock方法时可以直接参与state的修改之外,在tryAcquire方法代码中还可以看出区别。

公平锁代码中调用hasQueuedPredecessors方法,该方法主要判断当前节点是否除了head节点外还有其他节点等待获取锁

1:h != t 说明有独立于head的tail节点 ,代码结果为true,线程不能尝试锁的竞争

2:h.next == null,在AQS框架的源码中,当同步队列head获取到锁之后,会立即将next的节点设置为新的head节点并且执行next == null(GC回收),还是相当于h == t 。由于在高并发情况下多线程对数据的读取会存在不一致,如果h.next == null 说明独立于head的tail节点已经成为新的head节点,代码结果为true

3:s.Thread != Thread.currentThread(),如果当前是线程是锁的拥有者,则可以立即重入锁,无需排队

概括说明:当前只有一个节点,则可以立即竞争锁,如有多个节点则判断是否可以重入,绕过排队。

锁的释放

公平锁和非公平锁释放锁的过程都是一样的,无论当前锁是否有重入,释放锁的次数都必需等于获取锁的次数,每次释放state都会减去1,只到等于0为止。release是AQS的方法,当锁释放完毕之后,AQS会唤醒head节点去获取锁。

等待条件Condition

condition的作用是对锁进行更准确的控制

await : 线程阻塞等待,相当于Object的await方法

await(long time,TimeUnit unit) : 线程有时间的阻塞等待,相当于Object的await(long time)

signal : 线程唤醒,相当于Object类的notify

signalAll :唤醒所有await阻塞的线程,相当于Object类的notifyAll

直接使用ReentrantLock对象newCondition方法创建即可。

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

推荐阅读更多精彩内容