ReentrantLock非公平锁如何实现问题

阿萨德执行 2019-11-11 04:31:04
ReentrantLock是基于AQS方法完成的,如果是非公平锁,如果tryAcquire失败了,该线程addWaiter接在链表尾,后面再释放锁的时候unparkSuccessor()不就是唤醒后继的线程了?这不也是公平锁了吗?求大神解释
...全文
301 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuxm909 2019-11-12
  • 打赏
  • 举报
回复
失败就排队了。公平锁是直接排队,非公平锁是先尝试获取锁,失败再排队。不公平就体现在先尝试获取锁(插队)。
阿萨德执行 2019-11-12
  • 打赏
  • 举报
回复
引用 1 楼 yuxm909 的回复:
执行lock方法的线程不是先去排队,而是先尝试获取锁,这就是不公平。
获取锁的时候,是直接CAS锁状态,但是。如果获取锁失败呢。
q331691913 2019-11-12
  • 打赏
  • 举报
回复
= - =作为一个新手我对这门很就虐汪啊
yuxm909 2019-11-12
  • 打赏
  • 举报
回复
引用 7 楼 阿萨德执行 的回复:
[quote=引用 6 楼 yuxm909 的回复:]
ReentrantLock的lock方法,FairSync和NoFairSync的区别就在后者多了一个if cas的操作。

tryacquire也不同。只是这些不涉及我的问题[/quote]

我把自己的错误回复删了,避免误导他人。
刚才仔细看了源码,发现公平锁的tryAcquire方法多了hasQueuedPredecessors()的判断。
按我的理解,对于非公平锁,第一次尝试加锁失败后,线程就会按照队列顺序获取锁。
我看你写了AQS的几篇文章,感觉你都挺清楚了。
阿萨德执行 2019-11-12
  • 打赏
  • 举报
回复
引用 6 楼 yuxm909 的回复:
ReentrantLock的lock方法,FairSync和NoFairSync的区别就在后者多了一个if cas的操作。
tryacquire也不同。只是这些不涉及我的问题
阿萨德执行 2019-11-12
  • 打赏
  • 举报
回复
引用 3 楼 yuxm909 的回复:
失败就排队了。公平锁是直接排队,非公平锁是先尝试获取锁,失败再排队。不公平就体现在先尝试获取锁(插队)。
final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        // interrupted表示在CLH队列的调度中,
        // “当前线程”在休眠时,有没有被中断过。
        boolean interrupted = false;
        for (;;) {
            // 获取上一个节点。
            // node是“当前线程”对应的节点,这里就意味着“获取上一个等待锁的线程”。
            final Node p = node.predecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
按照acquireQueued(),当线程被unpark后,还是要去判断p == head才可以再去获取锁。
阿萨德执行 2019-11-12
  • 打赏
  • 举报
回复
引用 3 楼 yuxm909 的回复:
失败就排队了。公平锁是直接排队,非公平锁是先尝试获取锁,失败再排队。不公平就体现在先尝试获取锁(插队)。
按照你的意思,后面进入CLH队列的还是按照队列顺序获取锁?
yuxm909 2019-11-11
  • 打赏
  • 举报
回复
执行lock方法的线程不是先去排队,而是先尝试获取锁,这就是不公平。

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧