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