Go チャネルと Java BlockingQueue の間に違いはありますか? どちらも同様のブロッキングおよびメモリ モデルのセマンティクスを持つキューです。必要に応じて、両方に容量を設定できます。
4 に答える
最大の違いは、Go チャネルがselect
ステートメントをサポートしていることです。これにより、チャネル操作を 1 つだけ実行できます。例 ( 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")
}
}
この例では、c1 からの受信、c2 への送信、または c3 からの受信操作の 1 つだけが実行されます。選択に入ると、準備ができているチャネル (存在する場合) がランダムに選択されます。それ以外の場合、いずれかのチャネルの準備が整うまで操作がブロックされます。
Java ユーティリティを使用して、このチャネル選択をモデル化する簡単な方法を知りません。select
これはチャネルの設計ではなくステートメントの特性であると主張する人もいるかもしれませんが、私はそれがチャネルの設計の基本であると主張します.
もう 1 つの非常に重要な違いは次のとおりです。Go チャネルを閉じて、これ以上要素が来ていないことを知らせることができます。Java を使用することはできません。
例: goroutine A はファイルのリストを読み取ります。各ファイルをチャネルに投稿します。最後のファイルの後、チャネルを閉じます。goroutine B はチャネルからファイルを読み取り、何らかの方法で処理します。チャネルが閉じられると、ゴルーチンは終了します。
これを Java で行うのは簡単ではありません。ただし、いくつかの回避策があります。
それらは同様の方法で使用できます。
- どちらも、置く/送信または受け取る/受け取るときにブロックできます。
- 両方とも、送信がブロックされるタイミングを制御する容量があります。
おそらく最大の違いは、go チャネルが Java オブジェクトよりもかなり安価であることです。また、go チャネルを送信のみまたは受信のみに制限できるため、チャネルから送信できるユーザーと受信できるユーザーに関する追加のタイプの強制を保証できます。
Java で golang'select ステートメントに似た処理を行うには、java.nio パッケージを使用する必要があります。特にセレクターとチャンネル。ここでパッケージのドキュメントをチェックしてください:
http://docs.oracle.com/javase/6/docs/api/java/nio/channels/package-summary.html#multiplex
単一のスレッドを使用して複数のチャネルからの読み取り/書き込みを多重化することで、golang の select ステートメントとほぼ同じ機能を提供します。