0

この質問は、Java の最新バージョンに関するものです。

以下のサイズのプリミティブな 2 次元配列があります。

int[][] array = new int[numPasses][n*10]; //n threads write; during the i-th pass, the k-th thread writes to array[i] at locations k*10 to (k+1)*10-1.
//the array above is allocated at the beginning, and constantly rewritten. 

pass の間i、各nプロデューサー スレッドは 内の独自のメモリ ロケーションに書き込むarray[i]ため、書き込みプロセス中に競合状態は発生しません。書き込み後、mコンシューマー スレッドはこの書き込みの結果を読み取ります。array[i]すべての書き込みが完了する前に、消費者がいつでもアクセスする必要はありません。

私の最初の質問:次のような構造は、すべてのプロデューサ書き込みをキャッシュからフラッシュしますか? そうでない場合、プリミティブ配列に対してこれを行うにはどうすればよいでしょうか? (技術的な理由から、At​​omic*Array は使用できません。)

void flush() {//invoked after writes from all producer threads are done.

  if(producerThreadID == 0) {
  synchronized(array[i]) {//done at pass i.

  }
}

私の 2 番目の質問:これを行うためのより良い方法はありますか?

編集:わかりました、私がやりたいことは、空の同期ブロックでは本質的に不可能であることを受け入れます。上記の構造の代わりに、各プロデューサー スレッドが独自のパスにアクセスできるとします。

int[][] array = new int[numPasses][n*10]; //n = numPasses threads write; during the i-th pass, the i-th thread writes to all elements in array[i]. 

(これはZim-Zamの提案です。)

私の(できれば最後の)質問:synchronizedでは、i番目のスレッドの次の構造は、ブロック後の消費者スレッドの可視性を保証しますか?

//i-th producer thread acquires lock on array[i]
 void produce() {
   synchronized(array[i])

       //modify array[i][*] here
   }
4

2 に答える 2

0

私はあなたの理由を慎重に検討しますAtomics。なぜなら、それらはまさにあなたが必要としているものだからです.

本当に問題がある場合は、使用sun.misc.UnsafeのようにAtomics 使用することを検討しましたか?

または、フィールドを保持するオブジェクトの配列を使用しvolatileます。

class Vint {
  public volatile int i;
}
Vint[] arr = new Vint[10];

{
  for (int i = 0; i < arr.length; i++) {
    arr[i] = new Vint();
  }
}
于 2013-08-04T21:05:06.737 に答える