程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#線程系列講座(4):同步與死鎖(1)

C#線程系列講座(4):同步與死鎖(1)

編輯:關於C語言

雖然線程可以在一定程度上提高程序運行的效率,但也會產生一些副作用。讓 我們先看看如下的代碼:

class Increment
{
private int n = 0;
private int max;
public Increment(int max)
{
this.max = max;
}
public int result
{
get
{
return n;
}
set
{
n = value;
}
}
public void Inc()
{
for (int i = 0; i < max; i++)
{
n++;
}
}
}
class Program
{
public static void Main()
{
Increment inc = new Increment(10000);
Thread[] threads = new Thread[30];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(inc.Inc);
threads[i].Start();
}
for (int i = 0; i < threads.Length; i++)
{
threads[i].Join(); // 等待30個線程都執行完
}
Console.WriteLine(inc.result); //輸出n的值
}
}

上面的程序的基本功能是使用Increment的Inc方法為n遞 增max,所不同的是,將在Main方法中啟動30個線程同時執行Inc方法。在本例中 max的值是10000(通過Increment的構造方法傳入)。讀者可以運行一下這個程序 ,正常的結果應該是300000,但通常不會得到這個結果,一般獲得的結果都比 300000小。其中的原因就是Inc方法中的n++上,雖然從表面上看,n++只是一條簡 單的自增語言,但從底層分析,n++的IL代碼如下:

ldsfld// 獲得n的初 始值,並壓到方法棧中

ldc.i4.1// 將1壓到方法棧中

add// 從方 法棧中彈出最頂端的兩個值,相加,然後將結果保存在方法棧中

stfld// 從當前方法棧中彈出一個值,並更新類字段n

對於上面每一條IL語句是線 程安全的,但是n++這條C#語句需要上面的四步才能完成,因此,n++這條語句並 不是線程安全的。只要在執行stfld指令之前的任何一步由於其他線程獲得CPU而 中斷,那麼就會出現所謂的“髒”數據。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved