ReentrantLock的公平锁机制如何实现的?(源码理解)

公平锁是指多个线程按照申请锁的顺序来获取锁,即线程会直接进入队列中排队,队列中的第一个线程才能获得锁。这种机制确保了线程获取锁的公平性,避免了“饥饿”现象,即等待时间过长的线程无法获取到锁的情况。

默认情况下,ReentrantLock是非公平的,这是因为非公平锁的效率通常要高于公平锁。在没有特殊需求的情况下,一般推荐使用非公平锁,因为它能提供更高的性能。

通过查看ReentrantLock的构造方法,我们会发现有两种

 ReentrantLock lock = new ReentrantLock();
 ReentrantLock lock = new ReentrantLock(true);

 默认调用是NonfairSync()方法创建这个锁

公平锁的实现是在tryAcquire中实现的

 方法通过Thread.currentThread()获取当前线程对象,并将其赋值给变量current。然后,调用getState()方法获取当前锁的状态值,将其赋值给变量c

 判断状态值c是否为0。如果为0,表示锁未被占用,执行了hasQueuedPredecessors()方法

 

这个方法是用于判断当前线程是否有前驱节点在等待队列中。

方法首先获取尾节点(tail)和头节点(head),然后通过比较这两个节点是否相等来判断队列是否为空。如果头节点不等于尾节点,说明队列中有元素。

接下来,方法获取头节点的下一个节点(s = h.next),并检查该节点是否为null或者该节点的线程不是当前线程(s.thread != Thread.currentThread())。如果满足这些条件之一,说明当前线程有前驱节点在等待队列中,返回true;否则,返回false。

如果返回false就会执行compareAndSetState()方法,将状态值从0修改为acquires,则表示成功获取锁。之后调用setExclusiveOwnerThread(current)方法将当前线程设置为独占锁的拥有者。

如果状态值c不为0,表示锁已被占用。此时,需要进一步判断当前线程是否是锁的拥有者:

  1. 如果当前线程是锁的拥有者(即current == getExclusiveOwnerThread()),则可以将状态值增加acquires,并更新锁的状态值。
  2. 如果增加后的状态值nextc小于0,表示超过了最大锁计数,抛出异常。
  3. 更新锁的状态值为nextc
  4. 返回true表示成功获取锁。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ADRU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值