ReentrantLock的源码分析和核心思想介绍

ReentrantLock.lock() 核心步骤:

1. 尝试加锁

2. 加锁失败将,失败的线程加入等待队列

3. 让当前线程阻塞

ReentrantLock.unLock() 核心步骤:

1. 从队列中取出第一个有效的线程

2. 唤醒该线程,lock中的步骤3

相对于Synchronized,RentrantLock有一下特性:

1. 支持公平和非公平;

2. 支持中断lock1.lockInterruptibly();

3.需要手动加锁解锁;

ReentrantLock的核心思想:

第一. 自旋 while(true),没拿到锁就不断的尝试

第二. 加锁,保证只有一个线程可以拿到锁 CAS 加锁 compare and swap

第三. 双向链表, 用双向链表双向链表队列数据结构实现公平或非公平锁

第四. LockSupport 使用park()、unpark()实现阻塞

伪代码:

//加锁
//第一 自旋
while(true){ 
//第二 CAS 加锁
    if (unsafe.compareAndSwapInt(,,,)){ //加锁成功 
        break; //加锁成功的跳出循环
    }
    //将block的线程加入队列,以实现公平非公平锁 
    //第三 queue 记录需要加锁的线程
    HashSet.linkedQueue.add(thread); 
    //第四 利用park block 线程
    LockSupport.park();//加锁失败的在此等待 
}

//解锁
LockSupport.unpark(thread);

ReentrantLock的源码分析,公平锁部分:

reentrantLock.lock();

加锁入口:

进入类ReentrantLock的lock()方法:

进入FairSync实现类的lock方法中:

进入其Sync父类AbstractQueuedSynchronizer的acquire()方法:

第一步: 尝试获取锁

分析tryAcquire(arg), 下面的步骤7,实现了可重入锁的功能。

第二步:将当前线程加到等待队列中。

分析方法addWaiter()

分析方法enq()

第三步: 阻塞当前线程

分析方acquireQueued()

注意,这里的park会阻塞线程,所以当有unpark该线程时候,会从park的地方继续执行下去。

1. 分析方法shouldParkAfterFarledAcquire()

解析方法parkAndCheckInterrupt()。

调用LockSupport.park将当前线程阻塞住,等待白唤醒。

 

解锁入口:

解析方法release()

解析方法tryRelease(arg)

解析方法unparkSuccessor()

非公平锁部分如何实现:

如下图,对于非公平锁多了 一步直接去加锁的过程, 不管你等待队列里面有多少等待的,这里上来下试图去拿一下锁,获取锁不成功的情况下再尝试走下面的逻辑:

    

  

 每一个Node都有下面5个总有的属性:
prev             - 上一个Node
next             - 下一个Note
thread           - 保存线程,以便后面唤醒
SHARED/EXCLUSIVE - 独占、共享属性
waitStatus       - 节点的生命状态(信号量),包含下面值
    SINGAL     = -1  (可被唤醒)
    CANCELLED  = 1   (出现异常了,例如中断引起的)
    CONDITION  = -2  (条件等待)
    PROPAGATE  = -3  (传播)
    初始状态   = 0   (Node刚刚被创建出来默认0)

队列的样子大概长这样:

类的注意结构关系:
主类: ReentrantLock
ReentrantLock 中有个内部类: Sync, FairSync, NonfairSync
Sync 是 FairSync, NonfairSync的父类,即FairSync, NonfairSync是Sync的2个不同实现
Sync 继承自AbstractQueuedSynchronizer
AbstractQueuedSynchronizer中主要有Node相关实现,构建队列的数据结构
AbstractQueuedSynchronizer 又继承自AbstractOwnableSynchronizer
AbstractOwnableSynchronizer记录了那个线程拥有当前独占锁

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值