コードの一部を見てください
class Program
{
static void Main(string[] args)
{
var counter = new Counter();
var t1 = new Thread(() => TestCount(counter));
var t2 = new Thread(() => TestCount(counter));
var t3 = new Thread(() => TestCount(counter));
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
Console.WriteLine($"totalCount is {counter.Count}");
var counterNoLock = new CounterNoLock();
var t4 = new Thread(() => TestCount(counterNoLock));
var t5 = new Thread(() => TestCount(counterNoLock));
var t6 = new Thread(() => TestCount(counterNoLock));
t4.Start();
t5.Start();
t6.Start();
t4.Join();
t5.Join();
t6.Join();
Console.WriteLine($"Interlocked totalCount is {counterNoLock.Count}");
Console.ReadKey();
}
static void TestCount(CounterBase model)
{
for (int i = 0; i < 10000; i++)
{
model.Increment();
model.Decrement();
}
}
}
//计数基类
abstract class CounterBase
{
public abstract void Increment();
public abstract void Decrement();
}
//计数类
class Counter : CounterBase
{
private int _count;
public int Count
{
get
{
return _count;
}
}
public override void Increment()
{
_count++;
}
public override void Decrement()
{
_count--;
}
}
//计数类
class CounterNoLock : CounterBase
{
private int _count;
public int Count
{
get
{
return _count;
}
}
public override void Increment()
{
Interlocked.Increment(ref _count);
}
public override void Decrement()
{
Interlocked.Decrement(ref _count);
}
}
結果は
動作し
、3つのオブジェクトがTestCounter方法、オブジェクトの実行増減操作の方法を実行作成ランタイムコードをカウンタオブジェクトはスレッドセーフではないが、結果は最初の例の値であるので、競合状態が発生します不確かは、それがゼロであってもよいし、他の人のためかもしれません。
私たちは、オブジェクトをロックすることで、この問題を解決することができますが、これは、他のスレッドがブロックされるようになります、とインターロッククラスによって、あなたがオブジェクトをロックすることなく、正しい結果を得ることができ、インターロックは、基本的な数学演算インクリメント、デクリメント由来する方法を提供し、追加、などカウンタークラスを再書き込み私たちを助けるためにロックを使用しません。