构造了一个代码,请大侠看看,两种运行结果为 th1 th1 3 6 th2 th2 6 6 class Program { static void Main(string[] args) { Test t1 = new Test(); Test t2 = new Test(); Thread th1 = new Thread(t1.T); th1.Name = "th1";
// 下面两行互相注释运行出现两种不同的结果 //Thread th2 = new Thread(t1.T); Thread th2 = new Thread(t2.T); th2.Name = "th2"; th1.Start(); th2.Start();
} } class Test { private byte[] b = new byte[0]; public static int m = 0; public void T() { lock (b) { m++; m++; Thread.Sleep(100); m++; Console.WriteLine(Thread.CurrentThread.Name); Console.WriteLine(m.ToString()); } } }
直到第一个人上完WC,出来了,把门打开,第二个人才可以进去。
lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
th1 th1
3 6
th2 th2
6 6 class Program
{
static void Main(string[] args)
{
Test t1 = new Test(); Test t2 = new Test(); Thread th1 = new Thread(t1.T);
th1.Name = "th1";
// 下面两行互相注释运行出现两种不同的结果
//Thread th2 = new Thread(t1.T);
Thread th2 = new Thread(t2.T); th2.Name = "th2"; th1.Start();
th2.Start();
}
} class Test
{
private byte[] b = new byte[0]; public static int m = 0; public void T()
{
lock (b)
{ m++;
m++;
Thread.Sleep(100);
m++;
Console.WriteLine(Thread.CurrentThread.Name);
Console.WriteLine(m.ToString());
}
}
}
http://www.cnblogs.com/0754ydj/archive/2008/12/18/1357677.html
明显不一样啊,th1 就打印出 6 ,说明 th2 已经进到lock 块里执行了 ++ 操作了,把 Sleep 时间设置长一点更加明显
大括号{……}里的内容,是同步的
就是说,一个线程执行了里面的内容,如果有第二个线程也想执行里面的内容,那就要等前面的那个线程执行完了后才能执行,在第一个线程执行的期间,后面的那个线程,一直在等待执行,除非第一个执行完了
所以一般不要在实例中lock(this),因为实例的使用者也可能会lock此实例,容易导致死锁。若要在实例内部进行全局加锁,推荐创建一个私有成员,如object _thisLock=new object();把需要lock(this)的地方,替换为lock(_thisLock)。此例中也可以看出加锁与要锁的对象(类的实例)无关,锁仅是线程同步中的一种束定。并非你lock(someObject)后,其他线程就不能访问someObject,而是其他线程执行到同样的lock(someObject)代码段时需要审查锁的状况。
{
Moniter.Enter(someObject); //尝试进入临界区
//do something
}
catch{} //异常被忽略,没有任何处理
finally
{
Moniter.Exit(someObject); //退出临界区
}所以,若是确认不会发生异常的代码段加锁,推荐直接使用Moniter,因lock进行了异常检测,效率会有所损失。只有代码段可能会抛出异常且此异常无需处理的时候,才推荐使用lock。
你要资料的话,看看下面msdn在线连接,有实例。
http://msdn.microsoft.com/zh-cn/library/c5kehkcz.aspx