个人对于AQS和ReentrantLock的一些理解

本文深入解析了ReentrantLock的内部机制,包括其内部的Sync、NonfairSync和FairSync类。ReentrantLock作为可重入锁,允许线程多次获取同一锁。非公平锁在获取锁时遵循先到先得的原则,可能造成线程饥饿;而公平锁则确保线程按顺序获取锁。文章详细分析了非公平锁和公平锁在lock()方法中的实现流程,涉及CAS操作和AQS队列管理。
摘要由CSDN通过智能技术生成

ReentrantLock:

内部有三个final的静态内部类,其中Sync继承了AbstractQueuedSynchronizer(AQS),NonfairSync和FairSync则继承了Sync

  1. 和synchronized都属于<可重入锁>, 可重入锁代表, 在一个线程获取锁之后,该线程对该锁的其他后续操作都可以直接获得锁.

  2. 非公平锁 无参构造函数默认为非公平锁, 线程在竞争锁时,采取先到先得的方式

  3. 公平锁: 线程在竞争锁时,会以队列的形式进行排队

值得注意的是,非公平锁和公平锁,都能保证队列中排在前面的线程比排在后面的先获取锁,但非公平锁中,队列外的线程有可能比队列内的线程先获取到锁,这就提现了非公平性.

 

非公平锁lock()方法:

  1. 尝试CAS设置state的值

       若设置成功

  • 将该线程设置为该锁的占用线程

       若没有成功

  • 则调用AQS的acquire(1)方法

  • acquire(1)方法的第一个判断条件是   !tryAcquire(arg)  方法,arg就是acquire(1)的参数

  • 非公平锁对tryAcquire()方法的实现为:首先获取当前线程和当前锁的state值,若state值为0,代表该锁目前没有线程占用,则再次使用CAS去设置state,若设置成功,则将该线程设为该锁的占用线程,返回true.设置不成功,返回false.若state的值不为0并且当前线程是该锁的占用线程,将state值设为state+1,返回true.其他情况返回false,接着调用addWaiter(Node mode)方法,将线程加入等待队列,并调用 acquireQueued(),尝试让队列中的第一个Node中的线程去获取锁,获取成功,当前线程阻塞,lock()方法结束.

     

公平锁lock()方法:

  • 直接调用AQS的acquire(1)方法

  • 公平锁对tryAcquire()方法的实现为:首先获取当前线程和当前锁的state值,若state值为0,先调用hasQueuedPredecessors()方法判断队列中是否有等待的线程,如果有,则返回false,如果没有等待线程,则尝试使用CAS去设置state的值,若设置成功,则将该线程设为该锁的占用线程,返回true.设置不成功,返回false.若state的值不为0并且当前线程是该锁的占用线程,将state值设为state+1,返回true.其他情况返回false,接着调用addWaiter(Node mode)方法,将线程加入等待队列,并调用 acquireQueued(),尝试让队列中的第一个Node中的线程去获取锁,获取成功,当前线程阻塞,lock()方法结束.

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值