JAVA进阶之路-ReentrantLock的公平锁和非公平锁
Posted LuckyZhouStar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA进阶之路-ReentrantLock的公平锁和非公平锁相关的知识,希望对你有一定的参考价值。
通过学习AQS的原理,我们了解到,AQS内部是通过一个FIFO同步队列来完成同步状态的管理。当线程获取当前状态的时候(内部其实就是更新操作),同步器会将当前的状态构建成一个node节点对象,将其放入到同步队列中,同时底层调用LockSupport.park(this)来阻塞当前线程,释放cpu。当同步状态释放的时候,会把首节点进行环形,使其再次尝试获取同步状态。
那么内部的公平和非公平是如何来实现的呢?
ReentrantLock 的构造函数
public ReentrantLock()
sync = new NonfairSync();
/**
* Creates an instance of @code ReentrantLock with the
* given fairness policy.
*
* @param fair @code true if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair)
sync = fair ? new FairSync() : new NonfairSync();
我们可以看到,默认使用的是非公平锁,除非构造函数中传递参数True。
公平锁和非公平锁的区别点
非公平锁
final boolean nonfairTryAcquire(int acquires)
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0)
if (compareAndSetState(0, acquires))
setExclusiveOwnerThread(current);
return true;
else if (current == getExclusiveOwnerThread())
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
return false;
公平锁
protected final boolean tryAcquire(int acquires)
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0)
// 1. 和非公平锁相比,这里多了一个判断:是否有线程在等待
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires))
setExclusiveOwnerThread(current);
return true;
else if (current == getExclusiveOwnerThread())
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
return false;
//查询是否有其他的线程已经处于等待状态
public final boolean hasQueuedPredecessors()
Node h, s;
if ((h = head) != null)
if ((s = h.next) == null || s.waitStatus > 0)
s = null; // traverse in case of concurrent cancellation
for (Node p = tail; p != h && p != null; p = p.prev)
if (p.waitStatus <= 0)
s = p;
if (s != null && s.thread != Thread.currentThread())
return true;
return false;
总结
非公平锁的实现在刚开始获取锁的时候,直接使用了一次CAS去尝试获取锁,不成功才会构建node节点。而在公平锁中会首先判断是否已经有等待中的线程。这就是公平锁与非公平锁的差异所在。
1.非公平锁在调用lock后,会首先进行CAS抢锁,如果这个时候抢占到了,就直接返回true了
2.相对来说,非公平所性能会比较好一点,吞吐量比较大。
以上是关于JAVA进阶之路-ReentrantLock的公平锁和非公平锁的主要内容,如果未能解决你的问题,请参考以下文章
java ReentrantLock 公平锁 非公平锁 测试
java中ReentrantLock实现,公平锁和非公平锁,AQS并发队列,