Java 6 API 问题。调用是否与刚刚未停放的线程中的返回LockSupport.unpark(thread)
有发生之前的关系?LockSupport.park
我强烈怀疑答案是肯定的,但 Javadoc 似乎没有明确提及。
3 回答
我刚刚发现了这个问题,因为我问自己同样的事情。根据Oracle 研究员David Dice的这篇文章,答案似乎是否定的。这是文章的相关部分:
如果一个线程被阻塞,
park()
我们保证后续unpark()
将使它准备好。一个完全合法但质量低下的park()
and实现unpark()
将是空方法,其中程序退化为简单的旋转。事实上,这是正确使用的试金石。park()
unpark()
Emptypark()
和unpark()
methods 不会给你任何先发生关系的保证,所以为了让你的程序 100% 可移植,你不应该依赖它们。
再说一次,LockSupport 的 Javadoc说:
这些方法旨在用作创建更高级别同步实用程序的工具,它们本身对大多数并发控制应用程序没有用处。该
park
方法仅用于以下形式的构造:
while (!canProceed()) { ... LockSupport.park(this); }
由于无论如何您都必须明确检查某些条件,这将涉及volatile
或正确同步变量,因此弱保证park()
实际上应该不是问题,对吧?
如果没有这样记录,那么您不能依赖它来创建发生在关系之前的关系。
特别是 Hotspot 代码中的 LockSupport.java 只需调用 Unsafe.park 和 .unpark!
发生之前的关系通常来自易失性状态标志或类似的东西上的读写对。
请记住,如果它没有记录为创建之前发生的关系,那么即使您可以证明它在您的特定系统上确实如此,您也必须将其视为没有。未来的系统和实现可能不会。他们有充分的理由离开了自己的自由。
我查看了 JDK 代码,看起来 LockSupport 方法通常在同步块之外调用。所以,你的假设似乎是正确的。