Exchanger和SynchronousQueue之间的区别是什么?以及可以使用它们的场景?哪一个表现更好? (锁定明智吗?)
答案 0 :(得分:10)
Exchanger
更多是纯同步机制,而SynchronousQueue
另外提供标准队列数据结构的所有操作。这意味着您可以通过异步删除队列中的项目等来检查队列中的对象,取消已调度但尚未执行的操作等。 - Exchanger
不提供的操作。由于许多实现允许对队列大小设置限制,因此您可以获得对资源使用的额外控制,并且如果队列增长超过某个阈值,则可以删除请求。另一方面,Exchanger
提供开箱即用的双向通信,而单个队列只是一种方式(尽管可以手动实现另一方向的通信)。由于许多实际情况只需要生产者 - 消费者关系,因此队列通常更好,因为上面列出了更容易理解的API和其他操作。
This article描述了Exchanger
的实际用例。他们专注于在线程之间进行通信时能够避免创建和垃圾收集新对象(取决于实现,队列可能在您向其追加内容时分配条目)。性能可能取决于您的特定用例。在示例中,他们使用Exchanger
来提高效率(避免垃圾收集),但在大多数情况下(如果您不必提供亚毫秒延迟),分配一个或两个对象并不是一个大问题而且我我更喜欢使用队列进行额外的控制。
编辑:我在Oracle JDK中检查了Exchanger.java
的源代码,它确实在Exchanger.Node
中创建了类Exchanger.doExchange()
的临时对象。因此,似乎与链接文章状态的作者相反,Exchanger
不是免分配的。两者都不是(显然)LinkedBlockingQueue
。相反,ArrayBlockingQueue
在附加项目时不会分配任何临时对象。它只分配一个数组来保存创建时允许的最大元素数,但这只是一次性操作。在使用过程中,它不会创建新对象,因此从纯GC的角度来看,它应该优于Exchanger
。
答案 1 :(得分:2)
让我们关注关键点.. 交换器:是两个线程可以交换对象的集合点 SynchQueue:队列!一个线程放置并等待,直到另一个线程弹出 Exchanger是一种双向SyncQueue