還是先看例子:
public class Test
{
private void button1_Click(object sender, EventArgs e)
{
A a = new A();
B b = new B();
ThreadStart tsA = new ThreadStart(a.FunA);
ThreadStart tsB = new ThreadStart(b.FunB);
Thread ta = new Thread(tsA);
Thread tb = new Thread(tsB);
tb.Start();
ta.Start();
}
}
public class A
{
private string a = "ABC";
public void FunA()
{
lock (this.a)
{
MessageBox.Show(a);
}
}
}
public class B
{
private string b = "ABC";
public void FunB()
{
lock (this.b)
{
while (true)
{
Thread.Sleep(1);
}
}
}
}
當我們觸發button1_Click事件後,會有什麼結果?能否執行類A中的FunA方法彈出文本框"ABC" 答案是否定的
我們啓用了兩個線程,按道理講兩個方法都會執行的,爲什麼FunA 沒有執行呢,問題就出在了Lock上面;我們都知道lock 鎖確保當一個線程位於代碼的臨界區時,另一個線程不能進入臨界區。如果其他線程試圖進入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。
我們又問了,FunA裏面Lock的是類A中的string私有變量a;FunB裏面Lock的是類B中的string私有變量b;所以兩個線程Lock的是兩個不同的引用類型的值,又怎麼會影響呢;
問題就在於,Lock()裏面的值,在判斷是不是一個邊界時,比較的是裏面的值是否相等,如果相等,那麼他們就是一個邊界;很顯然類A中的string私有變量a的值"ABC"等於類B中的string私有變量b的值
總結 :對於多線程同步,我們要避免對string的lock