0

NasdaqIndex簡単な計算例を書きました。簡単にするために、私はそれをintと宣言しました。これは単なる株価の合計です10

class NasdaqIndex {

private int[] stockValue = new int[10]; // for simplicity let's assume they are already initialized

// just sum from 1 to 10 of stockValue
private int nasdaqIndexValue; // for simplicity let's assume that already initialized

public void StockValueUpdated(int stockValueIndex, int newValue) {
    int diff = newValue - stockValue[stockValueIndex];
    stockValue[stockValueIndex] = newValue;
    nasdaqIndexValue += diff;               // THIS NEED TO BE SYNCHRONIZED!
}

}

しかし実際には、StockValueUpdated は、異なる stockValueIndex に対して異なるスレッドから並列に呼び出される場合があります (また、並列に呼び出されることもあります) (同じ stockValueIndex に対して並列に呼び出されることはありません)。

したがって、コードの 1 行だけを同期する必要があります。nasdaqIndexValue += diff;

たとえば、あるスレッドが実行nasdaqIndexValue += 10;され、別のスレッドが実行されnasdaqIndexValue += 3;た場合、完全に正確13に追加されていることを確認する必要があります。この場合、同期はまったく必要ですか? もしそうなら、lock-freeコードを使用してそれを行う方法は?

UPD oooops double を使用している場合、そのようなコードを使用すると、毎回小さな「デルタ」が nasdaqIndex に導入されることに気付きました。したがって、小数を使用するか、nasdaqIndex を「完全に再計算」する必要がある場合があります。そうしないと、しばらくすると株式の合計と等しくなりません。

4

2 に答える 2

1

type を使用Interlockedして、その操作をアトミックにします。

Interlocked.Add(ref nasdaqIndexValue, diff);
于 2012-07-05T13:53:10.873 に答える
1

volatileキーワードを使用します。

volatile 修飾子は、通常、lock ステートメントを使用してアクセスをシリアル化せずに、複数のスレッドによってアクセスされるフィールドに使用されます。

private volatile int nasdaqIndexValue; // for simplicity let's assume that already initialized
于 2012-07-05T13:56:36.707 に答える