Java:LockSupport.parkNanos与Thread.sleep(...)

45
在某些情况下,我们中的大多数人会写出像这样的内容:
try {
   Thread.sleep(2000); 
} catch (InterruptedException e) {
   ; // do nothing
}

我并不关心这段代码对错与否,只是在某些测试工具中可以接受而已。 我的观点是:这段代码可以更简洁地写成:

  LockSupport.parkNanos(2000* 1000000);

是否有任何理由让我偏爱其中一种方法而不是另一种。


我的初步想法是,我发现理解2000毫秒比理解2000 * 1000000纳秒要容易得多! - Brian Agnew
3个回答

22

易读性: Thread.sleep 的含义很直观。如果你要向另一个开发人员描述你对 LockSupport.parkNanos 的使用,你会如何描述? 如果这个描述主要包括“我想让当前的线程 睡眠”,那么 Thread.sleep 显然更加描述性。

简洁之处在于缺乏中断处理 - 因此如果你想要,可以创建一个包装方法来处理中断,并将异常作为 RuntimeException 传播。实际上,如果你正在创建一个包装方法,你可以使用任意一种实现,尽管另一个线程当然也可以通过相同的方式解除阻塞“休眠”的线程......


主要区别不是在于sleep期间,处理器可以切换上下文到另一个线程,而是在于park仅等待一段时间(几乎像是带有空操作的循环)吗?(没有上下文切换-巨大的开销) - razor
@razor:不,我不认为那是这种情况——至少,文档没有明确说明它是自旋锁。 - Jon Skeet

22

parkNanos方法的文档提供了该方法可能返回的条件。其中之一是:调用无缘无故(也就是没有原因)返回。因此,如果你不介意偶尔的虚假唤醒和其他线程取消挂起等待线程的情况,那么使用这个方法就没有问题。当然,Jon的评论基本上解释了为什么会更喜欢其中一个而不是另一个。


3
我知道这个答案很老,但它仍然可以帮助寻找有关LockSupport更深入了解的开发人员。以下是一篇好文章,展示了这些虚假返回可能看起来像什么:https://hazelcast.com/blog/locksupport-parknanos-under-the-hood-and-the-curious-case-of-parking/ 简而言之,根据JVM(HotSpot,Dalvik,IBM)和主机,调用可能在几微秒后返回。 - Pierre Turpin

1

LockSupport的应用范围更为有限,不支持异常处理。如果您只需要锁定单个线程,则可以使用它。

从API中可以看到:

这些方法旨在用作创建更高级别同步工具的工具,并且本身对于大多数并发控制应用程序来说并不实用。


9
大多数时候,异常处理几乎没有什么用处。编程人员可以保证线程不会被中断...因此我的问题是什么。 - Zo72

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接