通知单个线程:notify、notifyAll还是concurrent.locks.Condition?

5
我有时需要唤醒或挂起一个单独的线程,我想知道最好和最有效的方法是什么。
第一种解决方案是结合使用信号和wait-notify(我知道如何正确实现这个模式,这不是问题)。
我在某处读到,使用java.concurrent库和CountDownLatch进行信号传递更有效。我也查看了concurrent.locks.Condition,但是主题表明,与notify/notifyAll相比,它只是一个(程序员方面)更安全和通用的构造, 并没有性能上的优势。Peter Lawrey在评论中建议使用Concurrency库而不是notify-notifyAll,因此现在我很困惑应该如何最佳实践。
相关问题:在我的情况下(即如果只有一个线程),notifynotifyAll哪个性能更好?我知道有很多类似的线程,但其中没有一个给出清晰的答案。在我的情况下,从功能上讲,我使用哪个都无所谓,但我想知道哪个更快。

我几乎总是会半信半疑地相信Peter Lawrey的建议。 - Eugene
只有在逻辑论点(正方和反方)平衡或问题是经验性的且无法通过分析方法来解决时,我才会这样做。 - Thomas Calc
2个回答

3

在性能方面,它们似乎并没有太大的区别,因为它们都暂停调用相应的wait线程,因此底层机制可能非常相似。而且为什么性能如此重要呢?除非您有一些极快的等待/信号模式,在这种模式中,信号在等待之后立即到来,从而使上下文切换过于昂贵,需要使用自旋锁代替,否则就不必担心性能问题。

你应该实现你认为最方便的编程方法,然后进行基准测试,看看是否真的需要更高性能的东西。


我会选择notify/notifyAll,但还有一个问题:为了向一个线程发出信号,哪个更有效率?这需要知道JVM对它们是如何实现的。我知道差异微不足道,但是喜欢其中一个胜过另一个不需要额外的优化工作(因为我只需要写“notify”或“notifyall”),所以我想使用“理论上”更好的解决方案(因为没有理由不这样做)。 - Thomas Calc
@Thomas Calc:你预计在应用程序中使用这些机制的频率有多高? - Tudor
这取决于用户输入,一般来说最坏情况下每秒一次。 - Thomas Calc
2
@Thomas Calc:我正在浏览源代码,但很难从中判断哪个更有效,因为它最终跳转到本地方法。你只能搜索这些机制的基准测试或自己进行测试。然而,即使每秒一个信号,我仍然认为差异并不重要。 - Tudor
1
如果有任何差异,那肯定是亚毫秒级别的,所以如果它每秒发生一次,显然没有必要担心它。 - assylias

0

wait-notify 完全没有问题。

因为等待列表上只有一个线程,所以在语义和性能方面,notifynotifyAll 没有区别。


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