2011-07-08 19 views
2

Interlockedクラスを使用してこれを行うためのきれいな方法はありますか?または、ちょうどlock { }を使用する必要がありますか?インターロックを使用してlongをテストし条件付きで更新する

具体的な使用例は、longの値を計算し、それを共有 "最大"値と比較する複数のスレッドがあり、ローカル値が大きい場合にのみ共有値を置き換えることです。

+2

ここで運が悪いと申し訳ありませんが、「ロック」を使用してください。 – Blindy

答えて

3

Interlocked.CompareExchangeメソッドを試してください。私は試していないが、このような何かが私に論理を思わ:

long localMax = Interlocked.Read(ref max); 
while (value > localMax) { 
    Interlocked.CompareExchange(ref max, value, localMax); 
    localMax = Interlocked.Read(ref max); 
} 

いつものように、ストレスが同時実行の問題をキャッチしようとするあなたのコードをテストします。

+0

'CompareExchange'は等しいかどうかだけをチェックします。あなたは "より大きい"比較などで行動することはできません。 – LukeH

+0

それを使用していません_alone _...私は更新しました。 –

+0

'max'フィールドの読み込みはスレッドセーフであるとは限りません。 – LukeH

0

あなたの共有フィールドの値が増えれば、ReadCompareExchangeの組み合わせでこれを行うことができます。

long sharedVal = Interlocked.Read(ref _sharedField); 
while (localVal > sharedVal) 
{ 
    long temp = Interlocked.CompareExchange(ref _sharedField, localVal, sharedVal); 
    sharedVal = (temp == sharedVal) ? localVal : temp; 
} 

しかし、私はこのような状況では、プレーンlockのために行くだろう:これはlockブロック未満読み取り可能で、あまりにも多くの貧しいパフォーマンスの可能性を持っているようInterlockedを使用します。

+0

これは無限ループになる危険はありませんか?最初に 'sharedField'が1で' localVal'が2であるとします。 'Interlocked.Read'の後に別のスレッドが入り込み、' sharedField'を3に設定します。 – Rob

+0

また、私はロックソリューションは確かに読みやすいとは認めていますが、インターロックされたソリューションはなぜパフォーマンスが低下するのでしょうか? – Rob

+0

@Rob:うん、それは間違いだった!あなたのコメントが現れる直前に私はすでに修正済みです。 – LukeH

関連する問題