闲谈ReentrantLock的实现原理

ReentrantLock

java除了使用关键字synchronized外,还可以使用ReentrantLock实现独占锁的功能。

而且ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。

  1. synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。
  2. synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。
  3. synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以相应中断。

ReentrantLock实现

ReentrantLock支持两种获取锁的方式,一种是公平模型,一种是非公平模型。

公平模型

  • 初始化时, state=0,表示无人抢占锁。这时候A线程请求锁,占了锁,并把state+1。
  • 线程B请求锁,线程B无法获取锁,生成节点进行排队。
  • 线程A释放了一次锁,仅仅是把state-1。只有线程A把此锁全部释放了,状态值减到0了,其他线程才有机会获取锁。
  • 当A把锁完全释放后,state恢复为0,然后会通知队列唤醒B线程节点,使B可以再次竞争锁。当一个线程节点被唤醒然后取得了锁,对应节点会从队列中删除。 
  • 如果B线程后面还有C线程,C线程继续休眠,除非B执行完了,通知了C线程。

非公平锁模型

  • 初始化时, state=0,表示无人抢占锁。这时候A线程请求锁,占了锁,并把state+1。
  • 线程B请求锁,线程B无法获取锁,生成节点进行排队。
  • 线程A释放了一次锁,仅仅是把state-1。只有线程A把此锁全部释放了,状态值减到0了,其他线程才有机会获取锁。
  • 当A把锁完全释放后,state恢复为0,然后会通知队列唤醒B线程节点,使B可以再次竞争锁。
  • 如果在唤醒B线程节点的过程中,线程C请求锁,线程C可能获取到锁。

公平锁的lock方法在进行cas判断时多了一个hasQueuedPredecessors()方法,它会在AQS队列中没有中没有线程的情况下才会申请锁,而不像非公平锁一样,非公平锁一来不管AQS里是否有排队的线程就直接申请锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值