还是先看例子:
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