2012-05-21 46 views
7

Go頻道和Java BlockingQueue之間有什麼區別嗎?兩者都是具有相似阻塞和內存模型語義的隊列。可選地,兩者都可以具有容量設定。Go頻道vs Java BlockingQueue

回答

12

我會說最大的不同是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實用程序對此通道選擇進行建模的任何微不足道的方法。有人可能會爭辯說,這是陳述的屬性,而不是渠道的設計,但我認爲這是渠道設計的基礎。

+1

我想你可以在阻塞隊列上使用poll方法關閉。但是你說得對,select語句爲多種不同渠道的複用提供了語法支持。 –

+1

對,我沒有提到忙等待,因爲我認爲這是一個非解決方案:-)。 –

2

它們可以以類似的方式使用。

  • 這兩者都可以阻止在發送/發送或接受/接收。
  • 兩者都有一個容量管理髮送將阻止。

最大的區別可能在於,通道比java對象便宜得多。並且可以將頻道限制爲僅發送或僅接收,這可以確保關於誰可以發送以及誰可以從頻道接收的一些附加類型強制執行。

+1

您是否有資料顯示他們便宜得多?這並不是說我不相信你,但是如果一些Java的隊列和nio頻道能夠跟上執行時間,我不會感到驚訝。不過,我確信Java在內存方面有所鬆動。 –

+0

@AdamGent恐怕我手頭沒有任何資源。儘管我主要談論內存不是執行速度。 –

3

在java中執行類似golang'select語句的操作需要使用java.nio包。具體選擇器和頻道。點擊這裏,查看包文檔:

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

它提供了幾乎相同的能力爲golang select語句,使用單線程復讀/從多個渠道寫作。

+2

Go通道允許傳輸任意數據結構(包括指針),但java.nio.channels只允許傳輸字節。我不認爲他們真的可比。 –

5

還有一個非常重要的區別是:您可以關閉一個Go頻道,以表示沒有更多元素即將到來。這是不可能的使用Java。

示例:goroutine A讀取文件列表。它將每個文件發佈到頻道中。在最後一個文件後,它關閉了頻道。 goroutine B從通道讀取文件並以某種方式處理它們。頻道關閉後,門廳關閉。

用Java做這件事並不容易;但是存在一些解決方法。

+1

確實!這是一個非常重要的區別。使用Java,您需要發送某種有毒記錄或流式結束字符,以表示沒有更多項目即將到來。這需要在雙方都有額外的代碼,參見[BlockingQueue的javadoc](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html): '一種常見的策略是爲了讓生產者插入特殊的流結束或毒物,並在消費者接受時進行相應的解釋 –