lock(obj) 鎖定obj 對象
lock(this) 鎖定 當前實例對象,如果有多個類實例的話,lock鎖定的只是當前類實例,對其它類實例無影響。
直接上代碼。
主窗體代碼如下:
delegate void SetTextCallback(string text);
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 利用委托設置 文本框內容
/// </summary>
/// <param name="text"></param>
public void SetText(string text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = this.textBox1.Text + "\r\n" + text;
}
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = "";
Thread[] thd = new Thread[500];
int intI = 0;
for (intI = 0; intI < 50; intI++)
{
thd[intI] = new Thread(new ParameterizedThreadStart(thdText));
thd[intI].Name = " Thread" + intI.ToString();
thd[intI].IsBackground = true;
thd[intI].Start(intI);
}
}
/// <summary>
/// 線程調用的方法
/// </summary>
/// <param name="obj"></param>
private void thdText(object obj)
{
oper op = new oper();
int intI = Convert.ToInt32(obj);
SetText(op.addition());
}
1、lock(obj)
添加oper類,代碼如下:
public class oper
{
private static object obj = new object();
private static Single slgTotal;
public string addition()
{
lock (obj)
{
int intI = 0;
slgTotal = 0;
for (intI = 0; intI <= 50; intI++)
{
slgTotal = slgTotal + intI;
Thread.Sleep(5);
}
return slgTotal.ToString() + " thread:" + Thread.CurrentThread.Name;
}
}
}
執行結果如下:
大家看到每個線程執行的結果都是相同的。下面來看lock(this)
2、lock(this)
將oper類代碼修改為如下:
public class oper
{
private static object obj = new object();
private static Single slgTotal;
public string addition()
{
lock (this)
{
int intI = 0;
slgTotal = 0;
for (intI = 0; intI <= 50; intI++)
{
slgTotal = slgTotal + intI;
Thread.Sleep(5);
}
return slgTotal.ToString() + " thread:" + Thread.CurrentThread.Name;
}
}
}
執行結果如下:
大家看到每個線程執行的結果都是不同的。
分析:lock(this) 鎖定的對象 是當前類實例,而每個線程操作的都是oper的新實例,lock(this)只對當前實例起作用,而slgTotal 是類的靜態變量,lock(this)實際上是沒在起起我們想要的結果。下面再看一種lock(obj)的實例
3、lock(obj) 這個第一個obj的demo稍有不同,即把oper類的obj靜態變量修改為變量,oper類修改為如下:
public class oper
{
private object obj = new object();
private static Single slgTotal;
public string addition()
{
lock (obj)
{
int intI = 0;
slgTotal = 0;
for (intI = 0; intI <= 50; intI++)
{
slgTotal = slgTotal + intI;
Thread.Sleep(5);
}
return slgTotal.ToString() + " thread:" + Thread.CurrentThread.Name;
}
}
}
執行結果如下:
此次運行結果和lock(this)結果是一樣的。這是為什麼呢?
總結:其實大家不要去看lock中鎖定的是this,還是obj,大家只要關心多線程鎖定的對象是不是為同一個對象。如果是同一個對象則會得到如上邊的demo1結果,否則則如demo2和demo3中的結果,也是我們不想要的。
摘自:李國清