有关lock和typeof定义

好文章,自己保存已备日后学习使用。原文出处:http://kenchell.blog.163.com/blog/static/26088309200821235841466/

lock 关键字可将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。
当一个lock已被占用时,在同一线程中执行的代码仍可以获取和释放该锁。但是,在其他线程中执行的代码在该锁被释放前是无法获得它的。
lock 语句的表达式必须表示一个引用类型的值。如果表达式表示的是一个值类型的值,则会导致一个编译时错误。
通常,如果要保护当前类,则 表达式 为 this

==================================================
lock后括号里面的值不是说把整个对象锁住,而是对他的标记进行了修改,使别的lock不能锁住他,这才是lock(object)的真面目.

我们lock住的是什么?是代码段,是lock后面大括号中代码段,这段代码让多个人执行不不被允许的.
那我们看lock(this), this是什么意思呢?可以说this只是这段代码域的标志(线程A中的lock需要等到线程B中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)将索引变为负数。

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

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

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

例如:
class Account
{
   int balance;
  public Account(int initial)
   {
      balance = initial;
   }
  int Withdraw(int amount)
   {
     lock (this)  //保护了当前类的方法Withdraw 线程
      {
         if (balance >= amount)
         {
             return amount;
         }
      }
   }
}
如果要保护 static 变量(或者如果临界区出现在类的静态方法中),则表达式为typeOf(class)
例如:
class AAA
{
   public static void Add(object x) {
      lock (typeof(AAA)) {  //保护了AAA类的静态方法Add 线程
         ...
      }
   }
   public static void Remove(object x) {
      lock (typeof(AAA)) {
         ...
      }
   }
}
======================================================
typeof 运算符用于获得某一类型的 System.Type 对象。
typeof(type) //type是 要获得其 System.Type 对象的类型。
不能重载 typeof 运算符。
若要获得一个表达式的运行时类型,可以使用 方法 GetType()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值