等待-通知和倒计时门闸之间的区别

7
我需要帮助理解使用CountDownLatch相比于传统的等待-通知机制的优势。我认为notifyAll()确实可以做到同样的事情,而且似乎更容易使用(可能是因为熟悉)。另外,wait()和CountDownLatch中的await()有什么区别?谢谢!
编辑: 我想重新表达我的问题:
根据文档,await()的作用是: 导致当前线程等待,直到计数器归零,除非线程被中断。
对我来说,很难看出wait()和await()之间的区别-await()在底层确实使用了wait(),并且似乎在计数达到零时有一个隐式的notifyAll()。
我的问题是,为什么我不应该只使用自己的计数变量处理的等待-通知机制,而要选择CountDownLatch呢?

1
这里有一个明显的区别...如果线程B在线程A调用wait()之前调用了notifyAll(),那么线程A将永远等待;但是如果线程B在线程A调用await()之前调用了countDown(),那么线程A将继续执行而不需要等待。 - yshavit
1个回答

11
它们肯定不是同一件事: CountDownLatch 只有在事件计数达到0时才会发信号,而且它会自动执行,wait-notify 要求你自己计数如果你想实现相同的行为。实现相同的行为常常容易出错,最好避免这样做(特别是如果你是新手并发编程)。比较 CountDownLatchwait-notify 几乎连苹果和橙子都不好比较,更像是比较自动钻和Allen扳手。
我不知道你是否使用过 notifyAll()CountDownLatch,但是仅使用 notifyAll() 是无法获得相同的行为,除非你已经计数了发生了多少事件。 CountDownLatch 可能最适合执行一定数量的任务,并在这些任务完成之前等待,然后再恢复程序其余部分的执行。当你有固定数量的线程(例如 ThreadPool)执行固定数量的任务,但是你的线程比任务要少得多并且必须重用它们时,它特别有帮助。使用 CountDownLatch 您可以轻松地等待所有任务完成。我不知道您如何使用 notifyAll() 来实现相同的行为,但是如果您提供更多信息,我们可以解决哪一个选择更好(肯定有一些情况下 waitNotify() 更合适)。
关于 wait()await() 的区别,我对你有点失望!查阅文档是任何问题的第一步:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

await()CountDownLatch 的一个实际函数,而 wait() 是从 Object 继承的。建议您查看文档以了解它们的功能。


你应该发布当前的文档。 - Hunter McMillen
@HunterMcMillen 哦,是的...那是个好主意 :)...(更新了文档) - Kiril
你说的“线程池执行固定数量的任务,但是你的线程比任务少得多,你必须重复使用它们”,是什么意思?如何实现n个线程执行m个任务(n < m)?你能提供一个演示吗? - coderz

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