10

次のように宣言された整数値を含む配列があります。

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]
4

6 に答える 6

6

複数のスレッドによる配列 (またはその他のコレクション、オブジェクトのフィールドなど) の内容の読み取りは、その間にデータが変更されない限り、スレッドセーフです。

処理するデータを配列に入力し、読み取りのために別のスレッドに渡すと、データは適切に読み取られ、データ競合は発生しません。

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

余談ですが、不変のコレクションを使用することをお勧めします。そうすれば、変更が不可能であることを保証できます。そのようなラッパーを使用することをお勧めします。パッケージを確認してくださいjava.util.concurrent.atomic。使用できるものがあるはずです。

于 2013-08-15T16:47:57.490 に答える
2

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

于 2013-08-15T16:48:01.677 に答える
0

ConcurrendLinkedQueueへの入力を検討し、各スレッドがそこからプルされるようにします。これにより、同時実行の問題がないことが保証されます。

スレッドはそれぞれ、キューの先頭からデータを取得して処理します。

于 2013-08-15T16:56:14.640 に答える
0

すべてのスレッドが読み取りのみであることを確認すると、スレッドセーフになります。ただし、その事実に依存するべきではなくalone、ラッパーを介して配列を不変にしようとします。

于 2013-08-15T16:48:55.750 に答える
0

確かに、それを読みたいだけなら、スレッドを作成するときに配列をスレッドに渡します。変更しない限り問題ありません。

于 2013-08-15T16:49:18.890 に答える