ReentrantLock如何实现公平和非公平锁?

本文讲解了ReentrantLock是如何实现公平和非公平两种锁的原理。

点击上方“后端开发技术”,选择“设为星标” ,优质资源及时送达

上一篇文章,我详细讲解了ReentrantLock的加锁和解锁的原理,请自行阅读。

5bbf50cef24cb00460f8104ddd390847.jpeg

重点,一文掌握ReentrantLock加解锁原理!|原创


看完之后,大家可能有一个疑问。

为什么继承AQS实现的ReentrantLock,获取锁不成功都需要进入同步队列,那后续解锁并且争夺锁的过程就是有序的,为什么会有公平和不公平?

实际上进入队列中挂起的线程确实是公平的,差别在于在进入队列之前的抢占过程,如下图。

0aff3d72f82376fcef08a86628fa3b4d.png

公平锁FairSync和非公平锁NonfairSync实现区别在于非公平锁会无视是否有已经排队的线程,直接与队头线程参与锁的竞争,具体细节如下:

1、 当有新的线程进入,非公平锁会直接加入争夺锁的过程,使用compareAndSetState()方法直接CAS抢占。而公平锁不会抢占,直接调用acquire()方法。

//非公平锁
final void lock() {// 直接参与争夺锁if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);
}
// 公平锁
final void lock() {acquire(1);
}

2、当初次尝试抢占失败的时候,非公平锁会在tryAcquire()方法中再次尝试抢占。而公平锁会先使用hasQueuedPredecessors()方法判断同步队列是否有前驱节点,如果没有的话才会加入抢占,否则进入队列排队。

//非公平锁
protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);
}
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) // overflowthrow 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) {// 判断是否有前驱节点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;
}

在进入队列参与锁竞争的逻辑之前讲过了,本文不再赘述。

最后,欢迎大家提问和交流。

如果对你有帮助,欢迎点赞、评论或分享,感谢阅读!

除了MVCC,Undo Log 还有哪些作用?|原创

2022-11-23

5e7225f4923f1ba3972bc7931700c53c.jpeg

update在MySQL中是怎样执行的,一张图牢记|原创

2022-11-19

652e3d745f231d484709f90996145cde.jpeg

MySQL主从数据不一致,怎么办?

2022-11-15

d367f3ba868956835828f3fcd5ee5793.jpeg


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部