ReentrantLock 继承于lock是比较常用的独占锁,接下来我们来分析一下ReentrantLock源码以及接口设计

Sync是ReentrantLock的内部静态抽象类继承AbstractQueuedSynchronizer类,ReentrantLock类部还有两个类FairSync(公平锁)跟NonfairSync(非公平锁)类实现Sync;

ReentrantLock默认内部是构建非公平锁,也可以制定使用公平锁跟非公平锁,

当调用lock()方法时,下面分析公平锁跟非公平区别:

lock()具体指向内部实例化的Sync对象

公平锁lock()方法直接调用acquire(1)直接尝试获取一次锁(第一次由于锁被抢占,加入队列时判断是否锁已经释放),如果失败后则加入队列

非公平锁,首先通过cas强行获取一次锁,失败后在调用acquire(1)尝试获取锁失败后加入队列

tryAcquire(1)方法实现也不同  非公平锁最终会调用Sync对象的nofairTryAcquire()方法,当state=0代表没有锁占用,此时会调用cas强行占用锁,

这时候如果同时新加入的线程抢占锁失败,导致后加入的锁进入队列,这时候体现无序不公平。

公平锁首先hasQueuedPredecessors()判断没有前驱节点代表是head节点然后再获取锁,

不管是公平锁还是非公平锁都支持重入锁,直接把state计数+1;

acquireQueued()方法主要左右是将实例化当前线程绑定Node节点加入队列并修改前驱节点Node的waitStatus为SIGNAL,同时并挂起当前节点;

首先new Node节点绑定线程,独占锁默认nextWaiter为空,如果存在tail节点然后通过cas添加tail节点,如果不存在会调用enq(node)方法初始化head节点

此时再次判断tail节点是否为空,如果为空然后cas添加一个空节点然后进入空转,下次循环再cas添加节点都tail节点,这里有人会疑问为什么会添加一个空Node节点而且并没有

绑定线程?

首先获取前驱节点,如果前驱节点是头节点,然后尝试获取一下锁,如果成功则设置当前node为head节点然后将前驱节点移除队列;

如果前驱节点不是头节点或者获取锁失败,此时进入shouldParkAfterFailedAcquire()方法

如果前驱节点是SIGNAL=-1则表示是可以挂起线程,等待前驱节点唤醒,如果前驱节点是刚才new Node() 的话

ws=0此时将会cas修改状态为SIGNAL,然后返回false然后进入自旋,再次进入此方法则再挂起当前线程。最后形成的链表处tail节点都是signal状态切线程状态都是挂起,

等待释放然后唤起header节点的next节点。

java源码-ReentrantLock源码分析-1的更多相关文章

  1. Java并发编程-ReentrantLock源码分析

    一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...

  2. Java并发之ReentrantLock源码解析(二)

    在了解如何加锁时候,我们再来了解如何解锁.可重入互斥锁ReentrantLock的解锁方法unlock()并不区分是公平锁还是非公平锁,Sync类并没有实现release(int arg)方法,这里会 ...

  3. Java并发之ReentrantLock源码解析(四)

    Condition 在上一章中,我们大概了解了Condition的使用,下面我们来看看Condition再juc的实现.juc下Condition本质上是一个接口,它只定义了这个接口的使用方式,具体的 ...

  4. Java并发编程 ReentrantLock 源码分析

    ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 这个类主要基于AQS(Abst ...

  5. java源码-ReentrantLock源码分析-2

    继续上篇ReentrantLock分析如何唤醒线程: 当调用lock.unlock()方法最终调用AQS类中的release方法,开始释放锁 tryRelease(1)方法在Sync对象中实现,首先会 ...

  6. Java并发之ReentrantLock源码解析(三)

    ReentrantLock和BlockingQueue 首先,看到这个标题,不要怀疑自己进错文章,也不要怀疑笔者写错,哈哈.本章笔者会从BlockingQueue(阻塞队列)的角度,看看juc包下的阻 ...

  7. Java并发之ReentrantLock源码解析(一)

    ReentrantLock ReentrantLock是一种可重入的互斥锁,它的行为和作用与关键字synchronized有些类似,在并发场景下可以让多个线程按照一定的顺序访问同一资源.相比synch ...

  8. Java并发系列[5]----ReentrantLock源码分析

    在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...

  9. Java并发编程之ReentrantLock源码分析

    ReentrantLock介绍 从JDK1.5之前,我们都是使用synchronized关键字来对代码块加锁,在JDK1.5引入了ReentrantLock锁.synchronized关键字性能比Re ...

随机推荐

  1. zabbix 邮件报警(五)

    一.sendEmail配置zabbix邮件报警 1.下载sendEmail: wget http://caspian.dotconf.net/menu/Software/SendEmail/sendE ...

  2. manjaro 常用软件安装

    1.搜狗输入法 sudo pacman -S fcitx-sogoupinyin fcitx-configtool fcitx-im yay -Sa fcitx-qt4 sudo vim /etc/e ...

  3. DP tricks and experiences

    [LeetCode] 关于动态规划的经验与技巧. 很多时候多分配一位空间是为了递推的方便,例如前推两位. 辅助数组的索引,用到的可能是 1 — N,或者是 0 — N-1. 具体要看清 f[i] 每一 ...

  4. Hadoop-No.9之表和Region

    影响性能与数据分布的一个因素是HBase中表的数量以及每个表的Region的数量.如果分配的不合理,集群一个节点活多个节点的负载会出现显著的不均衡. 其中比较注意的几点: - 每个节点包含一个Regi ...

  5. js自定义事件CustomEvent、Event、TargetEvent

    1.Event Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件通常与函数结合使用,函数不会在事件发生前被执行! Event的事件都是系统自 ...

  6. VC:检测网络连接的方法

    方法一: #include "stdafx.h" #include "windows.h" #include <Sensapi.h> #includ ...

  7. nginx负载均衡 页面缓存

    nginx的upstream目前支持4种方式的分配 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight 指定轮询几率,weight ...

  8. .net大文件传输断点续传源码

    IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...

  9. CTS添加新测试用例步骤

    一.CTS添加新测试用例: 前言: google源代码中的cts测试用例集目录为:source_android4.2/cts/tests/tests/ (source_android4.2表示andr ...

  10. MySQL的密码操作命令

    一.请问在win2K命令提示符下怎样更改mysql的root管理员密码? >mysql -u root -p Enter password: ****** mysql> use mysql ...