前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ReentrantLock是如何实现可重入性

ReentrantLock是如何实现可重入性

作者头像
算法与编程之美
发布2023-08-22 14:19:45
1570
发布2023-08-22 14:19:45
举报

1 问题

ReentrantLock是如何实现可重入性的? 并且在进入锁内之前进行了哪些判断?

2 方法

// Sync继承于AQSabstract static class Sync extends AbstractQueuedSynchronizer { ...}// ReentrantLock默认是非公平锁public ReentrantLock() { sync = new NonfairSync(); }// 可以通过向构造方法中传true来实现公平锁public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync();}protected final boolean tryAcquire(int acquires) { // 当前想要获取锁的线程 final Thread current = Thread.currentThread(); // 当前锁的状态 int c = getState(); // state == 0 此时此刻没有线程持有锁 if (c == 0) { // 虽然此时此刻锁是可以用的,但是这是公平锁,既然是公平,就得讲究先来后到, // 看看有没有别人在队列中等了半天了 if (!hasQueuedPredecessors() && // 如果没有线程在等待,那就用CAS尝试一下,成功了就获取到锁了, // 不成功的话,只能说明一个问题,就在刚刚几乎同一时刻有个线程抢先了 =_= // 因为刚刚还没人的,我判断过了 compareAndSetState(0, acquires)) { // 到这里就是获取到锁了,标记一下,告诉大家,现在是我占用了锁 setExclusiveOwnerThread(current); return true; } } // 会进入这个else if分支,说明是重入了,需要操作:state=state+1 // 这里不存在并发问题 else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } // 如果到这里,说明前面的if和else if都没有返回true,说明没有获取到锁 return false; }

3 结语

ReentrantLock使用内部类Sync来管理锁,所以真正的获取锁是由Sync的实现类控制的。在进行前先判断锁内是否有数据,没有锁就选择Sync继承AQS来实现进入锁内;如果锁内有数据则先判断数据是否是自己的,是自己的数据就将state的值+1,表示重入。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法与编程之美 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档