drainTo 方法行为的真实示例



我正在浏览 BlockingQueue 接口和 LinkedBlockingQueue 实现中存在的 drainTo 方法的 javadocs 和源代码。在查看源代码(JDK7)后,我对此方法的理解是,调用线程实际上提交了一个集合,然后获取了一个阻止其他消费者的takeLock()。之后,直到最大元素计数,节点的项将从队列中删除并放入集合中。

我可以欣赏的是,它可以避免线程一次又一次地获取锁,但请原谅我有限的知识,我无法理解在现实世界示例中需要相同的内容。有人可以分享一些现实世界的例子,其中 drainTo 行为是可观察到的?

好吧,我在现实生活中的代码中使用它,对我来说看起来很自然:后台数据库线程创建项目并将它们循环放入队列中,直到到达数据末尾或检测到停止信号。在第一项上,使用EventQueue.invokeLater启动 UI 更新程序。由于此invokeLater机制中的异步性质和一些开销,UI 更新程序需要一些时间才能查询队列,并且很可能有多个项目可用。

因此,它将使用drainTo来获取此特定点的所有可用项目,并更新一个ListDataModel,该为增加的间隔生成单个事件。可以使用其他invokeLater或使用Timer触发下一次更新。因此drainTo这里有"gimme 自上次调用以来到达的所有项目"的语义。

另一方面,轮询队列中的单个项目可能会导致生产者和消费者在短时间内相互阻止的情况,并且每次消费者请求新项目时,由于消费者被阻止的时间刚好足够长,生产者可以创建和放置一个新项目,因此另一个项目可用。因此,在这种情况下,您必须实现自己的时间限制,以避免阻止 UI 线程太久。使用一次drainTo,然后释放事件处理线程要容易得多。

最新更新