线程,同步与锁————Lock你到底锁住了谁

原文地址:http://www.cnblogs.com/city22/archive/2007/01/30/634948.html

 

     线程在多核时代的优势月来越明显,多线程编程的学习也提上议事日程。但越来越多的人陷入线程的泥潭,最后搞得自己面目全非。越来越多的死锁,越来越多的异常数据,在并发性测试中让一个个线程程序员焦头烂额。“自己在自己的编程环境下怎么都没事,单步调试也不会有任何错误,到了两个人,多个人测试的时候怎么就不行了呢?”线程,同步与锁的问题渐渐的凸现在了每个程序员的面前。
还是让我们一起来学习同步与锁吧。

      lock是每个程序员都熟知的语句,但究竟它如何工作的呢?
我们先来看几个案例,看看lock是什么.

 

 1       public   class  ThreadTest
 2      {
 3           private   int  i  =   0 ;
 4           public   void  Test()
 5          {
 6              Thread t1  =   new  Thread(Thread1);
 7              Thread t2  =   new  Thread(Thread2);
 8              t1.Start();
 9              t2.Start();
10          }
11           public   void  Thread1()
12          {
13               lock  ( this )
14              {
15                  Console.WriteLine( this .i);
16                  Thread.Sleep( 1000 );
17                  Console.WriteLine( this .i);
18              }
19          }
20           public   void  Thread2()
21          {
22              Thread.Sleep( 500 );
23               this .i  =   1 ;
24              Console.WriteLine( " Change the value in locking " );
25          }
26      }
27       public   class  ThreadTest2
28      {
29           private   int  i  =   0 ;
30           public   void  Test()
31          {
32              Thread t1  =   new  Thread(Thread1);
33              Thread t2  =   new  Thread(Thread2);
34              t1.Start();
35              t2.Start();
36          }
37           public   void  Thread1()
38          {
39               lock  ( this )
40              {
41                  Console.WriteLine( this .i);
42                  Thread.Sleep( 1000 );
43                  Console.WriteLine( this .i);
44              }
45          }
46           public   void  Thread2()
47          {
48               lock  ( this )
49              {
50                  Thread.Sleep( 500 );
51                   this .i  =   1 ;
52                  Console.WriteLine( " Can't change the value in locking " );
53              }
54          }
55      }

 

      两段程序有什么区别吗?看看吧,ThreadTest2.Thread2()中多了一个lock(this)却产生了不同的结果

      本想在案例一中lock住this对象,让其他的线程不能操作,可是事情不是像我们想象的那样lock(this)是lock this的意思.this中的属性依然能够被别的线程改变.那我们lock住的是什么?是代码段,是lock后面大括号中代码段,这段代码让多个人执行不不被允许的.那返回头来在看lock(this),this是什么意思呢?可以说this知识这段代码域的标志,看看案例二中Thread2.Thread2就明白了,Thread2中的lock需要等到Thread1种lock释放后才开始运行,释放之前一直处于等待状态,这就是标志的表现.

      好吧,让我们来了解一下,lock这段代码是怎么运行的.lock语句根本使用的就是Moniter.Enter和Moniter.Exit,也就是说lock(this)时执行Moniter.Enter(this),大括号结束时执行Monitor.Exit(this).他的意义在于什么呢,对于任何一个对象来说,他在内存中的第一部分放置的是所有方法的地址,第二部分放着一个索引,他指向CLR中的SyncBlock Cache区域中的一个SyncBlock.什么意思呢?就是说,当你执行Monitor.Enter(Object)时,如果object的索引值为负数,就从SyncBlock Cache中选区一个SyncBlock,将其地址放在object的索引中。这样就完成了以object为标志的锁定,其他的线程想再次进行Monitor.Enter(object)操作,将获得object为正数的索引,然后就等待。直到索引变为负数,即线程使用Monitor.Exit(object)将索引变为负数。

       如果明白了Monitor.Enter的原理,lock当然不再话下.当然lock后括号里面的值不是说把整个对象锁住,而是对他的一个值进行了修改,使别的lock不能锁住他,这才是lock(object)的真面目.

       但在实际使用中Monitor还是不推荐,还是lock好的,Monitor需要加上很多try catch才能保证安全性,但lock却帮我们做了,而且lock看起来更优雅.

       在静态方法中如何使用lock呢,由于我们没有this可用,所以我们使用typeof(this)好了,Type也有相应的方法地址和索引,所以他也是可以来当作lock的标志的.

       但微软不提倡是用public的object或者typeof()或者字符串这样的标志就是因为,如果你的public object在其他的线程中被null并被垃圾收集了,将发生不可预期的错误.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值