私はJavaが初めてで、longの2D配列で最大値を見つけるメソッドを作成しようとしています.
このメソッドは、個別のスレッドで各行を検索し、スレッドは共有の現在の最大値を維持します。スレッドは、自身のローカル最大値より大きい値を見つけると、この値を共有ローカル最大値と比較し、現在のローカル最大値と場合によっては共有最大値を適切に更新します。計算のインターリーブ方法に関係なく結果が正しいように、適切な同期が実装されていることを確認する必要があります。
私のコードは冗長で面倒ですが、まず、次の関数があります。
static long sharedMaxOf2DArray(long[][] arr, int r){
MyRunnableShared[] myRunnables = new MyRunnableShared[r];
for(int row = 0; row < r; row++){
MyRunnableShared rr = new MyRunnableShared(arr, row, r);
Thread t = new Thread(rr);
t.start();
myRunnables[row] = rr;
}
return myRunnables[0].sharedMax; //should be the same as any other one (?)
}
適合したランナブルの場合、私はこれを持っています:
public static class MyRunnableShared implements Runnable{
long[][] theArray;
private int row;
private long rowMax;
public long localMax;
public long sharedMax;
private static Lock sharedMaxLock = new ReentrantLock();
MyRunnableShared(long[][] a, int r, int rm){
theArray = a;
row = r;
rowMax = rm;
}
public void run(){
localMax = 0;
for(int i = 0; i < rowMax; i++){
if(theArray[row][i] > localMax){
localMax = theArray[row][i];
sharedMaxLock.lock();
try{
if(localMax > sharedMax)
sharedMax = localMax;
}
finally{
sharedMaxLock.unlock();
}
}
}
}
}
このロックの使用は、複数のスレッドが一度に干渉するのを防ぐ安全な方法だとsharedMax
思いましたが、同じ入力で非同時最大検出関数をテスト/比較すると、結果が正しくないことがわかりました. 私はちょうど私が言うという事実から問題が発生する可能性があると考えています
...
t.start();
myRunnables[row] = rr;
...
sharedMaxOf2DArray
関数で。おそらく、特定のスレッドは、myRunnables の配列に入れる前に終了する必要があります。そうしないと、間違った sharedMax を「キャプチャ」してしまうのでしょうか? それとも別のものですか?物事のタイミングについてはわかりません..