我正在查看 BlockingQueue 接口(interface)和 LinkedBlockingQueue 实现中存在的rainTo 方法的javadocs 和源代码。在查看源代码(JDK7)后,我对该方法的理解是,调用线程实际上提交了一个 Collection,然后获取了一个 takeLock(),这会阻塞其他消费者。之后,直到达到最大元素数,节点的项目将从队列中删除并放入集合中。
我可以欣赏的是,它使线程免于一次又一次地获取锁,但请原谅我有限的知识,我无法理解在现实世界的示例中是否需要相同的东西。有人可以分享一些现实世界中可以观察到 drakeTo 行为的例子吗?
最佳答案
嗯,我在现实生活中的代码中使用了它,它对我来说看起来很自然:后台数据库线程创建项目并将它们放入循环队列中,直到到达数据末尾或检测到停止信号。在第一个项目上,使用 EventQueue.invokeLater
启动 UI 更新程序。由于此 invokeLater
机制的异步性质和一些开销,UI 更新程序需要一些时间才能查询队列,并且很可能有多个项目可用。
因此,它将使用drainTo
获取在该特定点可用的所有项目,并更新ListDataModel
,该模型会为添加的时间间隔生成单个事件。可以使用另一个 invokeLater
或使用 Timer
触发下一次更新。因此,drainTo
的语义是“给出自上次调用以来到达的所有项目”。
另一方面,轮询队列中的单个项目可能会导致生产者和消费者在短时间内相互阻塞,并且每次消费者请求新项目时,都会有另一个项目可用,因为这样的情况消费者被阻塞的时间刚好足以让生产者创建并放置一个新项目。因此,您必须实现自己的时间限制,以避免在这种情况下阻塞 UI 线程太久。使用drainTo
一次并随后释放事件处理线程要容易得多。
关于java - danceTo 方法行为的真实示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21808729/