c# 原子操作


前言

在我們使用多線程的時候,我們會發現我們必須面臨一個線程安全的問題,就是說多個線程操作同一個數據可能產生的問題是否得到解決。

對於異步線程,常常提及到鎖這個概念,而我們知道鎖是一個非常消耗性能的東西,而對於c# 是給我們封裝了原子操作,對我們的鎖進行了一些優化。在多線程的時候我們依然可以用原子操作來實現減少性能的損耗。

正文

代碼如下:

static void TestCounter(CounterBase c)
	{
		for (int i = 0; i < 100000; i++)
		{
			c.increment();
			c.Decrement();
		}
	}
abstract class CounterBase {
	public abstract void increment();
	public abstract void Decrement();

}
class Counter : CounterBase
{
	private int _Count;
	public int Count => _Count;
   
	public override void increment()
	{
		//Console.WriteLine(CurrentThread.Name);
		_Count++;
	}
	public override void Decrement()
	{
		//Console.WriteLine(CurrentThread.Name);
		_Count--;
	}
}
class CounterWithLock : CounterBase
{


	private int _Count;
	public int Count => _Count;

	public override void increment()
	{
		Interlocked.Increment(ref _Count);
	}
	public override void Decrement()
	{
		Interlocked.Decrement(ref _Count);
	}
}

測試:

static void Main(string[] args)
{
	for (var i = 0; i < 100; i++)
	{
		var c = new Counter();
		var t1 = new Thread(() => TestCounter(c));
		var t2 = new Thread(() => TestCounter(c));
		var t3 = new Thread(() => TestCounter(c));
		t1.Start();
		t2.Start();
		t3.Start();
		t1.Join();
		t2.Join();
		t3.Join();
		Console.WriteLine(c.Count);
		var c1 = new CounterWithLock();
		t1 = new Thread(() => TestCounter(c1));
		t2 = new Thread(() => TestCounter(c1));
		t3 = new Thread(() => TestCounter(c1));
		t1.Start();
		t2.Start();
		t3.Start();
		t1.Join();
		t2.Join();
		t3.Join();
		Console.WriteLine(c1.Count);
	}
	Console.ReadKey();
}

結論

當我們使用原子操作的時候結果就為0,這個很好的解決了我們的死鎖問題,因為只有原子操作完,其他線程才可以進行操作。

原子操作的原理

后續補齊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM