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

有一个作为参数的对象,在该参数的后面还有一个一次只能由一个线程执行的代码块

参数必须为基于引用类型的对象 该对象用来定义锁的范围

在上例[private void Function(){lock(obj){}}]中,锁的范围限定为此函数,因为函数外不存在任何对该对象的引用

提供给 lock 的对象只是用来唯一地标识由多个线程共享的资源,所以它可以是任意类实例

此对象通常表示需要进行线程同步的资源

eg:如果一个容器对象将被多个线程使用,则可以将该容器传递给 lock,而 lock 后面的同步代码块将访问该容器。只要其他线程在访问该容器前先锁定该容器,则对该对象的访问将是安全同步的。

最好避免锁定 public 类型或锁定不受应用程序控制的对象实例 如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致

死锁 [ 两个或更多个线程等待释放同一对象]

锁定公共数据类型(相比于对象)也可能导致问题

锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留,这意味着整个程序中任何给定字符串都只有一个实例

就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本

只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例

某些类提供专门用于锁定的成员。例如,Array 类型提供 SyncRoot。许多集合类型也提供 SyncRoot

private static object syncCSListLock = new object();.

lock (syncTSLock)

lock(x)

{

    DoSomething();

}

等价于

System.Object obj = (System.Object)x;

System.Threading.Monitor.Enter(obj);

try

{

    DoSomething();

}

finally

{

    System.Threading.Monitor.Exit(obj);

}



作者:水木