【发布时间】:2012-05-28 06:11:03
【问题描述】:
Go 通道和 Java BlockingQueue 之间有什么区别吗?两者都是具有相似阻塞和内存模型语义的队列。 (可选)两者都可以设置容量。
【问题讨论】:
标签: java concurrency go channel
Go 通道和 Java BlockingQueue 之间有什么区别吗?两者都是具有相似阻塞和内存模型语义的队列。 (可选)两者都可以设置容量。
【问题讨论】:
标签: java concurrency go channel
我想说最大的区别是 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 语句的属性,而不是通道的设计,但我认为这是通道设计的基础。
【讨论】:
另一个非常重要的区别是:您可以关闭 Go 频道以表示没有更多元素即将到来。使用 Java 是不可能的。
示例:goroutine A 读取文件列表。它将每个文件发布到频道中。在最后一个文件之后,它会关闭通道。 goroutine B 从通道中读取文件并以某种方式处理它们。通道关闭后,goroutine 退出。
在 Java 中做到这一点并不容易;但是存在一些解决方法。
【讨论】:
a common tactic is for producers to insert special end-of-stream or poison objects, that are interpreted accordingly when taken by consumers.
它们可以以类似的方式使用。
最大的区别可能是 go 通道比 java 对象便宜得多。并且可以将 go 频道限制为仅发送或仅接收,这可以确保对谁可以发送以及谁可以从频道接收进行一些额外的类型强制。
【讨论】:
要在 java 中执行类似于 golang'select 语句的操作,需要使用 java.nio 包。特别是选择器和通道。在此处查看软件包文档:
http://docs.oracle.com/javase/6/docs/api/java/nio/channels/package-summary.html#multiplex
它提供与 golang 选择语句几乎相同的功能,使用单个线程从多个通道多路读取/写入。
【讨论】: