2012-01-23 14 views
31

データの配列があるとしますが、2つのスレッドが同じ配列の異なるインデックスに同時に安全に書き込むことはできますか?私は書き込みのスピードが心配で、私はビットと実際の書き込みとの間に 'get index at write'を同期させたい。Java並行処理 - 同じ配列の異なるインデックスに書き込む

2つのスレッドで同じインデックスが取得されないと想定できるコードを記述しています。

+4

インデックス* i *に1つのスレッドが書き込みを行い、インデックス* i *からもう1つのスレッドに書き込みを行いますか? – aioobe

+0

使用している配列クラスのタイプによって異なります。もっと情報を提供できますか? – Michael

+0

助けてくれてありがとう。 –

答えて

33

アレイ内の2つの異なるインデックスの場合、2つの別々の変数と同じ規則が適用されます。

Java言語仕様の章"Threads and Locks"は示すことによって開始します:

17.4.1共有変数

[...]

すべてのインスタンスフィールド、静的フィールドと配列要素はヒープメモリに格納されます。 この章では、変数という用語を使用して、両方のフィールドと配列要素を参照します。

これは、安全に2つの異なるインデックスに同時に書き込むことができることを意味します。 コンシューマスレッドがプロデューサスレッドによって書き込まれた最後の値を確認するようにするには、同じインデックスに書き込み/読み取りを同期させる必要があります。

+2

+1はJLSからの引用です。 –

+0

恐ろしい情報。ここにはちょっとした問題があります:仕様のこの部分に従わないJavaの実装はありますか? – TreyE

+3

いいえ、それはJavaの実装としてカウントされないため、そうですか? :) – aioobe

11

2つの異なるスレッドで2つの異なる変数を変更することは安全です。配列内の2つの異なる要素を変更することは、少なくともOSに関する限り、異なるメモリアドレスの下で2つの異なる変数を変更することと比較することができます。だからはい、それは安全です。

0

CopyOnWriteArrayListを参照してください。ただし、あなたはarrayListでも構いません。そのドキュメント、

からのArrayListのスレッドセーフな変異体は、全ての変更操作 は(セットを追加する、など) 基礎となる配列の新しいコピーを作成することによって実現されます。

これは通常、あまりにも高価であるが、トラバーサル操作が大幅に変異を上回ったときに代替 よりも効率的であり、そしてあなたがまたはトラバーサルを同期させたい、まだ同時スレッド間 の干渉を排除する必要がないことができないとき 便利です。 は、複数の同時読み取り可能にすること

そして

CopyOnWriteArrayListとのインスタンスがリストの実装として動作し、そしてためには 書き込みと同時に発生すること読み出します。これを行う方法は、毎回 という名前のリストを新しいコピーにすることです。

読み取りはブロックされず、実質的に揮発性読み取りのコストのみを支払う。 書き込みは読み取りをブロックしません(またはその逆)。書き込みは1回だけ行うことができます。

+3

値を書き込むたびにデータ構造全体のコピーを作成することをお勧めしますか? – aioobe

1

ええ、それは技術的には真ですが、この回答には非常に多くの注意点がありますので、私はあなたにはいっていると非常に心配しています。配列内の2つの異なる場所に書き込むことはできますが、同時実行性の問題にぶつかることなく他のことを行うことはできません。あなたがこれを行うことができるなら、次に何をするつもりなのでしょうか?

アレイが異なる場所に書き込んだときに移動するカウンタ変数がある場合は、並行性の問題が発生する可能性があります。あなたの配列がいっぱいになると、2つのスレッドが同じ場所に試して書き込むことができる可能性があります。あなたが潜在的に同じ場所を読むことができる配列のリーダーを持っていれば、並行処理の問題が発生します。あなたがそれを読み返すことを決して予定していないのであれば、書き込み以外に何もしないのですが、読者を追加するときに並行性の問題があると思います。それでは、スレッドがデータの上書きをしない場所に移動するのではないかという疑問があります。スレッドがどこに書き込むかの頭を動かしたことがないなら、なぜあなたは配列を使用していますか?彼らに個々のラッチや変数を書いて、本当にそれらを分離しておくだけです。

「はい」と言っているあなたの意図が完全にわからないと、あなたが何をやっているのかを考えずに危険につながる可能性があります。

+3

彼はアレイの重複していない部分を同時に書き込む複数の "ライター"スレッドを持つことができ、すべてが完了するとすべてが書き込まれます。その後、きめ細かい同期は必要ありません。 – Alpedar

関連する問題