首先先上官方Msdn的说法:

  lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
  lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit。 ThreadInterruptedException 引发,如果 Interrupt 中断等待输入 lock 语句的线程。
  通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。

  常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
  如果实例可以被公共访问,将出现 lock (this) 问题。
  如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
  由于进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。
  最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。
  在 lock 语句的正文不能使用 等待 关键字。

lock 语句的表达式必须表示一个引用类型的值。永远不会为 lock 语句中的表达式执行隐式装箱转换,因此,如果该表达式表示的是一个值类型的值,则会导致一个编译时错误。

C#中引用类型主要有:数组、类、接口、委托、object、字符串,但是最好不要锁字符串;使用lock同步时,应保证lock的是同一个对象,而给字符串变量赋值并不是修改它,而是重新创建了新的对象,这样多个线程以及每个循环之间所lock的对象都不同,因此达不到同步的效果。常用做法是创建一个object对象,并且永不赋值。

private static object objlock = new object();

private
static object _staticObject; public static object StaticObject {  get { if(_staticObject==null)//判断为空 { lock(objlock)//加锁 { if(_staticObject==null)//再次判断             _staticObject=new object();//初始化 } }     return _staticObject; } }

 

posted on 2018-03-01 15:57  庭前竹  阅读(150)  评论(0)    收藏  举报