Go 通道 vs Java BlockingQueue

Posted

技术标签:

【中文标题】Go 通道 vs Java BlockingQueue【英文标题】:Go channel vs Java BlockingQueue 【发布时间】:2012-05-28 06:11:03 【问题描述】:

Go 通道和 Java BlockingQueue 之间有什么区别吗?两者都是具有相似阻塞和内存模型语义的队列。 (可选)两者都可以设置容量。

【问题讨论】:

【参考方案1】:

我想说最大的区别是 Go 通道支持 select 语句,它允许您只执行一个通道操作。一个例子(由Go language specification修改):

select 
case i1 = <-c1:
    print("received ", i1, " from c1\n")
case c2 <- i2:
    print("sent ", i2, " to c2\n")
case i3, ok := (<-c3):  // same as: i3, ok := <-c3
    if ok 
        print("received ", i3, " from c3\n")
     else 
        print("c3 is closed\n")
    

在此示例中,将执行从 c1 接收、发送到 c2 或从 c3 接收操作中的一个。进入选择时,会随机选择一个就绪通道(如果有)。否则,操作会阻塞,直到其中一个通道准备好。

我不知道使用 Java 实用程序来模拟此频道选择的任何简单方法。有人可能会说这是select 语句的属性,而不是通道的设计,但我认为这是通道设计的基础。

【讨论】:

我认为您可以在阻塞队列上使用 poll 方法接近。但是你说得对,select 语句为在多个不同通道上的多路复用提供了语法支持。 对,我没有提到忙等待,因为我认为这是一个非解决方案:-)。【参考方案2】:

另一个非常重要的区别是:您可以关闭 Go 频道以表示没有更多元素即将到来。使用 Java 是不可能的。

示例:goroutine A 读取文件列表。它将每个文件发布到频道中。在最后一个文件之后,它会关闭通道。 goroutine B 从通道中读取文件并以某种方式处理它们。通道关闭后,goroutine 退出。

在 Java 中做到这一点并不容易;但是存在一些解决方法。

【讨论】:

确实!这是一个非常重要的区别。使用 Java,您需要发送某种有害记录或流结束字符来表示没有更多项目即将到来。这需要两边额外的代码,见javadoc of BlockingQueue:a common tactic is for producers to insert special end-of-stream or poison objects, that are interpreted accordingly when taken by consumers. 有人知道为什么 BQ 没有关闭吗?它看起来简单但有用且必不可少【参考方案3】:

它们可以以类似的方式使用。

在放置/发送或接收/接收时,两者都可以阻挡。 两者都具有控制发送何时阻塞的容量。

最大的区别可能是 go 通道比 java 对象便宜得多。并且可以将 go 频道限制为仅发送或仅接收,这可以确保对谁可以发送以及谁可以从频道接收进行一些额外的类型强制。

【讨论】:

你有资料证明它们便宜得多吗?并不是我不相信你,但如果 Java 的某些队列和 nio 通道能够在执行时间方面跟上,我不会感到惊讶。不过,我确信 Java 在内存方面有所松懈。 @AdamGent 恐怕我手头没有任何消息来源。我主要是在谈论内存而不是执行速度。【参考方案4】:

要在 java 中执行类似于 golang'select 语句的操作,需要使用 java.nio 包。特别是选择器和通道。在此处查看软件包文档:

http://docs.oracle.com/javase/6/docs/api/java/nio/channels/package-summary.html#multiplex

它提供与 golang 选择语句几乎相同的功能,使用单个线程从多个通道多路读取/写入。

【讨论】:

Go 通道允许传输任意数据结构(包括指针),但 java.nio.channels 只允许传输字节。我认为它们没有可比性。

以上是关于Go 通道 vs Java BlockingQueue的主要内容,如果未能解决你的问题,请参考以下文章

Golang✔️走进 Go 语言✔️ 第十六课 协程 & 通道

go语言--通道

Go笔记(十四):通道 channel

Go channel VS Java BlockingQueue

Java19 虚拟线程 VS Go 协程 的吞吐量

Java19 虚拟线程 VS Go 协程 的吞吐量