2013-08-15 9 views
8

私は整数値を含む配列を持っているが、このように宣言:アレイからの同時読み取りはスレッドセーフですか?

int data[] = new int[n]; 

それぞれの値が処理されると、それは別々のスレッドで処理できるように、私は粉々に作業を分割しています必要があります。処理中に配列は変更されません。

すべての処理スレッドは、アレイの別々の部分を同時に読み取ることができますか?または、私はロックを使用する必要がありますか?

つまり、この作業命令はスレッドセーフですか?複数のスレッドによるアレイ(または他の任意のコレクション、オブジェクトのフィールドなど)の

Array is created and filled 
Threads are created and started 
Thread 0 reads data[0..3] 
Thread 1 reads data[4..7] 
Thread 2 reads data[8..n] 
+0

任意の数のスレッドが値を読み取ることができます。クリティカルセクションは、執筆が関係している場合にのみ重要です。 – Jyro117

+0

@ Jyro117または読書!構造体の反復処理は同期させる必要があります。 –

+0

構造体が不変であると扱われている場合、つまり構造体内部のデータへの書き込みがない場合は、構造体を同期させる必要はありません。読み込み時に構造が変更されない限り、配列は決して発生しません。 – Jyro117

答えて

6

読み取り内容は、データがその間に変更されないことを条件とするスレッドセーフです。

処理するデータで配列を塗りつぶし、読み取りのために別のスレッドに渡すと、データが正しく読み取られ、データの競合は発生しません。

これは、配列を埋め込んだ後にスレッドを作成した場合にのみ機能することに注意してください。すでに存在するスレッドに同期化せずに処理のために配列を渡すと、配列の内容が正しく読み込まれないことがあります。そのような場合、同期ブロックはスレッド間でメモリ更新を強制するため、スレッドが配列への参照を取得する方法を同期させる必要があります。

サイドノート:不変のコレクションを使用するとよいでしょう。そのようにしても、修正はできません。私はそのようなラッパーを使用することをお勧めします。 java.util.concurrent.atomicパッケージをチェックすると、使用できるものがあるはずです。

+0

クイック返信をありがとう。逆も可能ならば、私はさまよっていましたが、そのスレッドは同時に同じことができます(これらのスレッドは同じインデックスには絶対になりません) – user2342875

+0

@ user2342875あなたは書き込みを意味しますか?異なるスレッドから異なるメモリ位置に書き込む場合、同期を使用しない場合、メモリが正しく新しい値で別のスレッドから読み取られるかどうかは決して確かではありません。同期化は、スレッド間のメモリ同期も保証します。 – Dariusz

+0

@ user2342875私は自分の答えを書き直し、潜在的な落とし穴を挙げました。あなたのコードでそれを考慮してください。 – Dariusz

2

スレッドが配列内の内容を変更しない限り、複数のスレッドから配列を読み取っても問題ありません。

0

すべてのスレッドが読み込み中であることを確認した場合は、スレッドセーフです。その事実に頼るべきではありませんが、あなたの配列をラッパーを介して不変にしようとしてください。

0

確かに読んでみたいのであれば、作成時に配列にスレッドを渡してください。あなたがしない限り何の問題もありませんそれを変更します。

0

アレイアレイから読み取るのはスレッドセーフな操作ですが、配列を変更する場合はクラスAtomicIntegerArrayを使用することを検討してください。

0

ConcurrendLinkedQueueを設定し、各スレッドにプルします。これにより、並行性の問題が発生しないことが保証されます。

スレッドは、それぞれのデータをキューの上部から取り出して処理しています。