gpt4 book ai didi

java - 在这种情况下,是否有可能与 ConcurrentHashMap 陷入僵局?

转载 作者:行者123 更新时间:2023-12-01 08:28:08 31 4
gpt4 key购买 nike

我正在阅读 ConcurrentHashMap 的源代码在 JDK8 中,请注意 TreeBin使用“读写”锁来防止并发读写。

如果没有尝试修改树结构的并发写入线程,则读取线程将通过 TreeNode。 “查找”操作完成后,读取线程可能会:

(1)'CAS'lockState并“解开”服务员(作家)线程(如果存在)。

以下是源代码中的“find()”方法。

final Node<K,V> find(int h, Object k) {
if (k != null) {
for (Node<K,V> e = first; e != null; ) {
int s; K ek;
if (((s = lockState) & (WAITER|WRITER)) != 0) {
if (e.hash == h &&
((ek = e.key) == k || (ek != null && k.equals(ek))))
return e;
e = e.next;
}
else if (U.compareAndSwapInt(this, LOCKSTATE, s,
s + READER)) {
TreeNode<K,V> r, p;
try {
p = ((r = root) == null ? null :
r.findTreeNode(h, k, null));
} finally {
Thread w;
// (1)if no more readers, try to unpark the waiter if it exists
if (U.getAndAddInt(this, LOCKSTATE, -READER) ==
(READER|WAITER) && (w = waiter) != null)
LockSupport.unpark(w);
}
return p;
}
}
}
return null;
}

另一方面,作者线程可能:
  • (2) 添加 WAITER状态到 lockState使用“CAS”操作。
  • (3) 将自己设置为 waiter多变的。
  • (4)“ parking ”本身。

  • 这是作者的代码:

            private final void contendedLock() {
    boolean waiting = false;
    for (int s;;) {
    if (((s = lockState) & ~WAITER) == 0) {
    if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) {
    if (waiting)
    waiter = null;
    return;
    }
    }
    else if ((s & WAITER) == 0) {
    if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
    waiting = true;
    waiter = Thread.currentThread();
    }
    }
    else if (waiting)
    LockSupport.park(this);
    }
    }

    这是我的困惑:

    如果上面的四个操作按 (2) (1) (3) (4) 的顺序运行,则操作 (1) 将不会解锁任何东西,因为此时 'waiter' 为空。

    然后服务员将永远 parking ,没有任何人可以打开它。

    随后的写入将全部阻塞在“停放”线程持有的内在锁上。

    这是一个陷入僵局的机会吗?

    我真的很困惑。我想也许我在源代码中遗漏了一些东西。如果您熟悉它,需要您的帮助。

    最佳答案

    这个问题已经超过一年了。但这是一个很好的谜题。答案如下:

    在(2)(1)(3)之后,在conventionedLock()中继续执行如下:
    if (((s = lockState) & ~WAITER) == 0)因为(1)被执行了
    if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER))也是 , 因为 (3) 是在 (s = lockState) 之前执行的而不是在它之后

    waiting在执行 (3) 第三个 if 语句之前设置为 true 也是 .因此 waiter设置为空,我们退出循环。 (4) 从不执行。

    把它们加起来:
    在 (2) (1) (3) 之后,将永远不会执行操作 (4)。所以没有死锁的机会,我们都可以毫无顾虑地继续使用 ConcurrentHashMap ;-)

    关于java - 在这种情况下,是否有可能与 ConcurrentHashMap 陷入僵局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55314733/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com