更新:
当我第一次发布这个时,我相当肯定代码被破坏了.现在,我不再确定我观察到了什么.我遇到的最大问题是我似乎无法应用
17.4. Memory Model并直接说明它是否应该起作用.
以下代码已被破坏.
它对于它想要实现的目标来说过于复杂,但此外,它的线程不安全因为我发现它可以无限期地等待c.我并不担心前者(可以使用ReentrantLock或CountDownLatch作为更健全的代码),但我想知道,后者的原因是什么?
static final ConcurrentHashMap mutex = new ConcurrentHashMap<>();
public static brokenFoo() {
Object ourLock = new Object();
for (;;) {
Object theirLock = mutex.putIfAbsent(0, ourLock);
if (theirLock == null) {
break;
}
synchronized (theirLock) { // a
if (mutex.get(0) != theirLock) { // b
continue;
}
theirLock.wait(); // c
} // d
}
try {
// critical section
} finally {
synchronized (ourLock) { // e
mutex.remove(0); // f
ourLock.notifyAll(); // g
} // h
}
}
> hb(f,h)和hb(h,a)因此hb(f,a)
> hb(c,d)和hb(d,e)因此hb(c,e)
但是,这似乎并没有证明或反驳任何事情.
编辑:(上面的问题无法真正解释这段代码应该做什么.)
预期:
> brokenFoo()由多个线程调用,上面的代码应该提供//关键部分的互斥.
>如果两个或多个线程同时输入brokenFoo(),则只有一个线程应该进入//临界区,而其他线程则先于某个位置等待.
>在//关键部分中的线程退出后,另一个应继续取代它.
实际:
>据观察,即使没有其他线程在brokenFoo()中,也存在等待c的线程.