我正在通过阻塞问题接口和LinkedBlockingQueue实现的drainTo方法的javadocs和源代码。在查看源代码(JDK7)之后,我对此方法的理解是,调用线程实际上提交了一个Collection,然后获取了一个takeLock(),它阻止了其他消费者。在此之后,直到max元素的计数,节点的项目将从队列中删除并放入集合中。
我可以理解的是,它可以避免线程一次又一次地获取锁定,但请原谅我有限的知识,我无法理解在现实世界中的例子需要相同的内容。有人可以分享一些可以观察drainTo行为的现实世界的例子吗?
答案 0 :(得分:0)
好吧,我在现实代码中使用它,对我来说看起来很自然:后台数据库线程创建项目并将它们放入循环中的队列,直到到达数据末尾或检测到停止信号。在第一项上,使用EventQueue.invokeLater
启动UI更新程序。由于此invokeLater
机制的异步特性和一些开销,它需要一些时间,直到UI更新程序到达查询队列的位置,并且很可能有多个项目可用。
因此,它将使用drainTo
获取此特定点可用的所有项目,并更新ListDataModel
,这会为添加的时间间隔生成单个事件。可以使用其他invokeLater
或使用Timer
触发下一次更新。所以drainTo
的语义为“gimme自上次调用以来所有项目到达”。
另一方面,轮询单个项目的队列可能会导致生产者和消费者在短时间内相互阻塞的情况,并且每当消费者要求新项目时,由于事实,另一个项目可用消费者被阻止的时间足够长,生产者可以创建并放置一个新项目。因此,您必须实现自己的时间限制,以避免在这种情况下阻止UI线程太长时间。使用drainTo
一次并在之后释放事件处理线程要容易得多。