複数のスレッドから符号なし整数を増分したい。
Interlocked.Increment については知っていますが、符号なし整数は処理されません。lock() を使用することもできますが、パフォーマンス上の理由から、可能であれば使用しないことをお勧めします。
通常の方法で増分するだけでスレッドセーフになりますか? 統計にのみ使用されるため、時折の増分が失われても問題ありません。値が破損するのは望ましくありません。
ベストアンサー1
パフォーマンス上の理由で使用したくないとおっしゃっていますlock
が、テストしましたか? 競合のないロック (どうやらそうである可能性が高いようです) はかなり安価です。
私は通常、スレッド処理に関しては、「巧妙でパフォーマンスが優れている可能性がある」よりも「明らかに正しい」ことを選びます (一般的には、特にスレッド処理に関しては)。
ロックありとロックなしのアプリをベンチマークし、違いがわかるかどうかを確認します。ロックによって重要な違いがあるなら、もちろん、巧妙なものを使います。そうでなければ、私はロックに固執します。
あなたがかもしれないやりたいことは、Interlocked.Increment
を で使用しint
、必要に応じて をキャストして を取得することですuint
。次のようにします。
using System;
using System.Reflection;
using System.Threading;
public class Test
{
private static int count = int.MaxValue-1;
public static uint IncrementCount()
{
int newValue = Interlocked.Increment(ref count);
return unchecked((uint) newValue);
}
public static void Main()
{
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
}
}
出力:
2147483647
2147483648
2147483649
(つまり問題なくラップされます。)