Javaでは、複数のスレッドがそれぞれプリミティブ(ダブル)配列のセクションを分離するために非同期で書き込みを行い、すべてのスレッドが書き込みを完了したときにメインスレッドが配列から読み取ります。配列に同時に書き込むときの可視性の問題
- プリミティブ配列のスレッドローカルバージョンを読み書きする機会がありますか?
- 1.もし真であれば、これはメインスレッドの読み込みの前にメモリバリアを追加することで解決できますか?どちらをお勧めしますか?
下記のコード例。事前に
多くのおかげで、 マヌエル
//Example code to calculate distance of 1 point to 1mln other points:
double[][] history = this.createRandomMatrix(1000000,8);
double[] order = this.createRandomMatrix(1,8)[0];
double[] result = new double[1000000];
for(int i = 0; i< 100;i++){
pool.execute(new Calculator(history, newPoint, result,i*10000,10000 + i * 10000));
}
pool.shutdown();
try {
pool.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//read happens here
//Calculator run function
public void run() {
for(int i = start;i<end;i++){
result[i] = this.computeDistance(history[i],order);
}
}
ありがとう、スレッドローカルバージョンが作成されない理由を尋ねることができます(私の場合、結果は静的ではありません - ちょうどコードスニペット)。データの競合は起こりませんが、メインスレッドはワーカースレッドのすべての書き込みを読み取ることができると思います。なぜなら、それがその後に発生したとしても?私はいくつかのテストを実行することでこれを観察します。 – user1578796
開始するすべてのワーカースレッドに対して変数のスレッドローカルバージョンが作成された場合、スレッドを使用する必要はなく、ワーカースレッドの結果をメインスレッドの変数に格納する必要があります。スレッドローカルは、スレッドセーフではないオブジェクトがあるのにそのオブジェクトへのアクセスを同期させたくない場合に使用されます。あなたの質問では、 "すべてのスレッドが書き込みを完了したら、メインスレッドは配列から読み込みます。"私が得たことは、ワーカースレッドが完了するまでメインスレッドを一時停止することです。 – pahan
申し訳ありません - 私は "スレッドローカル"の私の使用法はミスリーディングだと思います - 私は、個々のスレッドが結果配列またはそのフィールドをキャッシュし、メインスレッドが配列から読み取るまでフラッシュしないことを意味します。私はThreadLocalのターゲットを絞った使い方について話しているわけではありません。 – user1578796