Java NIO Pipe 与 BlockingQueue
我刚刚发现它只有一个 NIO 工具,即 Java NIO Pipe,它是为在线程之间传递数据而设计的。与通过队列(例如 ArrayBlockingQueue)传递的更传统的消息相比,使用此机制是否有任何优势?
I just discovered that just has an NIO facility, Java NIO Pipe that's designed for passing data between threads. Is there any advantage of using this mechanism over the more conventional message passing over a queue, such as an ArrayBlockingQueue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通常,将数据传递给另一个线程进行处理的最简单方法是使用 ExecutorService。这封装了一个队列和一个线程池(可以有一个线程)。
当您有一个支持 NIO 通道的库时,您可以使用 Pipe。如果您想在线程之间传递数据的 ByteBuffer,它也很有用。
否则,使用 ArrayBlockingQueue 通常会更简单/更快。
如果您想要一种更快的方式在线程之间交换数据,我建议您查看 Exchanger 但它不像 ArrayBlockingQueue 那样通用。
Exchanger 和无 GC Java
Usually the simplest way to pass data for another thread to process is to use an ExecutorService. This wraps up both a queue and a thread pool (can have one thread)
You can use a Pipe when you have a library which supports NIO channels. It is also useful if you want to pass ByteBuffers of data between threads.
Otherwise its usually simple/faster to use a ArrayBlockingQueue.
If you want a faster way to exchange data between threads I suggest you look at the Exchanger however it is not as general purpose as an ArrayBlockingQueue.
The Exchanger and GC-less Java
我相信 NIO Pipe 的设计是为了让您可以以线程安全的方式将数据发送到选择器循环内的通道,换句话说,任何线程都可以写入管道,并且数据将在管道的另一个极端进行处理,在选择器循环内。当您写入管道时,您可以使另一端的通道可读。
I believe a NIO Pipe was designed so that you can send data to a channel inside the selector loop in a thread safe way, in other words, any thread can write to the pipe and the data will be handled in the other extreme of the pipe, inside the selector loop. When you write to a pipe you make the channel in the other side readable.
因此,在管道遇到很多麻烦之后(查看此处)我决定支持非阻塞并发队列而不是 NIO 管道。所以我对Java的ConcurrentLinkedQueue做了一些基准测试。见下文:
结果:
结论:
maxTime 可能很可怕,但我认为可以安全地得出结论,我们轮询并发队列的时间处于 50 纳秒范围内。
So after having a lot of trouble with pipe (check here) I decided to favor non-blocking concurrent queues over NIO pipes. So I did some benchmarks on Java's ConcurrentLinkedQueue. See below:
The results:
Conclusion:
The maxTime can be scary but I think it is safe to conclude we are in the 50 nanos range for polling a concurrent queue.
我认为管道将具有更好的延迟,因为它很可能通过幕后的协程来实现。因此,当数据可用时,生产者立即让步给消费者,而不是当线程调度程序决定时。
管道通常代表消费者-生产者问题,并且很可能以这种方式实现,以便两个线程协作并且不会被外部抢占。
I suppose the pipe will have better latency as it could very likely be implemented with coroutines behind the scenes. Thus, the producer immediately yields to the consumer when data is available, not when the thread scheduler decides.
Pipes in general represent a consumer-producer problem and are very likely to be implemented this way so that both threads cooperate and are not preempted externally.