C#中lock用法详解

2019-12-26 11:52:16刘景俊
易采站长站为您分析C#中lock用法,以实例形式详细分析了lock语句的用法及用途,需要的朋友可以参考下    

本文实例讲述了C#中lock的用法。。具体分析如下:

lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。

先来看看执行过程,代码示例如下:

lock 语句用于获取某个给定对象的互斥锁,执行一个语句,然后释放该锁。 
lock-statement:(lock 语句:) 

复制代码 lock(expression) embedded-statement(lock   (   表达式   )   嵌入语句)
lock 语句的表达式必须表示一个引用类型的值。永远不会为 lock 语句中的表达式执行隐式装箱转换,因此,如果该表达式表示的是一个值类型的值,则会导致一个编译时错误。

 

下列形式的 lock 语句:

复制代码 lock (x) ...
(其中 x 是一个引用类型的表达式)完全等效于
复制代码 system.threading.monitor.enter(x);
try {
   ...
}
finally {
   system.threading.monitor.exit(x);
}
不同的只是:实际执行中 x 只计算一次。
当一个互斥锁已被占用时,在同一线程中执行的代码仍可以获取和释放该锁。但是,在其他线程中执行的代码在该锁被释放前是无法获得它的。

 

一个类的 system.type 对象可以方便地用来当作关于该类的静态方法的互斥锁。例如:

复制代码 class cache
{
   public static void add(object x) {
      lock (typeof(cache)) {
         ...
      }
   }
   public static void remove(object x) {
      lock (typeof(cache)) {
         ...
      }
   }
}
假设线程a先执行,线程b稍微慢一点。线程a执行到lock语句,判断obj是否已申请了互斥锁,判断依据是逐个与已存在的锁进行object.referenceequals比较(此处未加证实),如果不存在,则申请一个新的互斥锁,这时线程a进入lock里面了。
这时假设线程b启动了,而线程a还未执行完lock里面的代码。线程b执行到lock语句,检查到obj已经申请了互斥锁,于是等待;直到线程a执行完毕,释放互斥锁,线程b才能申请新的互斥锁并执行lock里面的代码。