2010-03-19 46 views
7

Java 6 API问题。是否LockSupport.unpark(thread)有一个发生在之间的关系从LockSupport.park返回在刚刚unparked线程?我强烈怀疑答案是肯定的,但Javadoc似乎没有明确提及它。Java LockSupport内存一致性

回答

1

我已经查看了JDK代码,它看起来像LockSupport方法通常在同步块之外调用。所以,你的假设似乎是正确的。

+1

很抱歉对这样一个旧的答案发表评论,但是由于问题是关于Java * API *而不是Sun/Oracle提供的*实现*,所以查看JDK如何使用'LockSupport'并不是100%正确的。 JDK开发人员可能会对其自己的实现做出假设,而便携式应用程序则不应该这样做。另外,还有一些方法可以实现* happen-before *关系,而不涉及任何'synchronized'块。 – rolve 2013-12-02 13:28:39

+0

“......通过JDK代码查看”:您是否可以为OpenJDK发布一个hg URL? – kevinarpe 2015-12-17 08:29:58

5

如果它没有记录成这样,那么你不能依靠它创建关系之前发生的事情。

特别是Hotspot代码中的LockSupport.java只需调用Unsafe.park和.unpark!

发生在之间的关系通常来自易失性状态标志或类似物上的写读取对。

请记住,如果没有记录为创建之前发生关系,那么你必须把它当作虽然它不能使用,即使你能证明它特定的系统上。未来的系统和实现可能不会。他们有充分的理由让自己离开了自由。

6

我刚刚发现这个问题,因为我问自己同样的事情。根据Oracle研究人员David Dicethis article,答案似乎是没有。下面是文章的相关部分:

如果一个线程被阻塞在park()我们保证后续 unpark()将使它准备。 park()unpark()的执行完全合法但是质量较差 将是空方法,其中 程序退化为简单旋转。 其实这就是 石蕊试验正确park() - unpark()的用法。

park()unpark()方法不给你任何之前发生关系的保证,所以对于你的程序是100%可移植的,你不应该依赖他们。

话又说回来,Javadoc of LockSupport说:

这些方法被设计用来作为工具,用于创建 更高级别的同步实用程序,而不是本身对于大多数并发控制应用 有用。该park方法 只在形式的结构设计用于:

while (!canProceed()) { ... LockSupport.park(this); }

既然你反正明确检查一些条件,这将既涉及volatile或适当地同步变量,弱担保park()实际上不应该是问题,对吧?

+2

感谢您的回答。我现在不记得为什么我想知道这一点。我怀疑我是在想,当正在运行的线程更新条件并调用'unpark'时,如果它本身能够保证未停放的线程能够看到更新后的状态处于一致状态。看起来没有保证,所以唯一安全的选择是为条件更新明确安排记忆障碍。 – Lachlan 2013-11-30 12:03:02

+0

我明白了。如果'park()'和'unpark()'之间存在一个*发生之前*关系,那么这个条件就不需要涉及内存屏障。所以这个问题仍然有效。 – rolve 2013-12-02 13:24:26