JMM 和 trylock 的不良使用

JMM and Undesirable use of trylock

对 trylock 的不当使用

T1                                   T2
x = 42;                              while (lock.trylock())
lock.lock();                               lock.unlock();
                                     assert(x == 42);

在java和c++内存模型中都允许x=42在lock(1)之后移动。 因此断言可能会在 T2 线程中失败。因此在 C++ 内存模型中 他们定义 trylock 失败的行为可能是 spurious。 但是我没有在 java 内存模型中找到 trylock 的规格。 可以在线程 2 中断言保证在 Java 中通过。参考会有帮助!

参考: http://rsim.cs.illinois.edu/Pubs/08PLDI.pdf

来自 Lock 的 javadoc:

Unsuccessful locking and unlocking operations, and reentrant locking/unlocking operations, do not require any memory synchronization effects.

如果 trylock 成功获取锁,它将与 T1 的先前锁同步。通过锁语义,我们知道当我们进入循环时 T1 不可能有一个先前的锁。因此,如果我们进入循环,则与 T1 没有同步关系。

如果(或何时)trylock 失败,则与 T1 没有同步关系。至少,如果我们假设 trylock 失败是 "unsuccessful locking operation",正如 所暗示的那样。

因此无论如何,赋值和断言之间不存在happens-before关系。因此,我们有一个数据竞争,x 的值可能是也可能不是 42。

我找不到任何明确 Java trylock 可能是 "spurious" 的东西。但是,此示例在 Java.

中具有虚假行为

尽管如此,JavaDoc for trylock

Acquires the lock if it is available and returns immediately with the value true.

但在我看来,语言规范胜过 JavaDoc。