简体   繁体   English

Go channel vs Java BlockingQueue

[英]Go channel vs Java BlockingQueue

Are there any differences between a Go channel and a Java BlockingQueue? Go通道和Java BlockingQueue之间有什么区别吗? Both are queues with similar blocking and memory model semantics. 两者都是具有类似阻塞和内存模型语义的队列。 Optionally both can have a capacity set. 可选地,两者都可以具有容量集。

I would say the biggest difference is that Go channels have support for the select statement, which allow you to perform exactly one channel operation. 我想说最大的区别是Go通道支持select语句,它允许你只执行一个通道操作。 An example (altered from the Go language specification ): 一个例子(改为Go语言规范 ):

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")
    }
}

In this example, exactly one of the receive-from-c1, send-to-c2, or receive-from-c3 operations will be performed. 在此示例中,将执行从c1接收,从c1发送到c2或从c3接收操作中的一个。 When entering the select, a ready channel (if any) is selected randomly. 进入选择时,随机选择就绪通道(如果有)。 Otherwise, the operation blocks until one of the channels is ready. 否则,操作将阻塞,直到其中一个通道准备就绪。

I'm not aware of any trivial way to model this channel selection using the Java utilities. 我不知道使用Java实用程序对这个通道选择建模的任何简单方法。 One could argue that this is a property of the select statement rather than the design of channels, but I would argue that it's fundamental to the design of channels. 有人可能会说这是select语句的属性而不是通道的设计,但我认为它是通道设计的基础。

One more very important difference is: You can close a Go channel to signal that no more elements are coming. 另一个非常重要的区别是:您可以关闭Go通道以表示不再有元素出现。 That is not possible using Java. 使用Java是不可能的。

Example: goroutine A reads a list of files. 示例:goroutine A读取文件列表。 It posts each file into the Channel. 它将每个文件发布到Channel中。 After the last file, it closes the channel. 在最后一个文件之后,它关闭了频道。 goroutine B reads the files from the channel and processes them in some way. goroutine B从通道读取文件并以某种方式处理它们。 After the channel is closed, the goroutine quits. 通道关闭后,goroutine退出。

Doing this in Java is not easily possible; 用Java做这件事并不容易; however some workarounds exist. 但是存在一些变通方法。

They can be used in similar ways. 它们可以以类似的方式使用。

  • Both can block on when putting/sending or taking/recieving. 两者都可以在发送/发送或接收/接收时阻止。
  • Both have a capacity that governs when sending will block. 两者都具有控制发送何时阻止的容量。

The biggest differences are probably that go channels are considerably cheaper than a java object. 最大的区别可能是通道比java对象便宜得多。 and that go channels can be restricted to only send or only receive which can ensure some additional type enforcement regarding who can send and who can receive from a channel. 并且可以将频道限制为仅发送或仅接收,这可以确保关于谁可以发送以及谁可以从频道接收的一些附加类型强制执行。

To do something similar to golang'select statement in java would involve using the java.nio package. 在java中执行类似golang'select语句的操作将涉及使用java.nio包。 Specifically selectors and channels. 特别是选择器和通道。 Check out the package docs here: 在这里查看包文档:

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

It offers pretty much the same capability as the golang select statement, using a single thread to multiplex reading/writing from multiple channels. 它提供与golang select语句几乎相同的功能,使用单个线程来复用多个通道的读/写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM