欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#中实现线程同步lock关键字的用法详解

程序员文章站 2022-05-18 13:01:51
1. lock关键字保证一个代码块在执行的过程中不会受到其他线程的干扰,这是通过在该代码块的运行过程中对特定的对象加互斥锁来实现的。 2. lock关键字的参数必须是引用...

1. lock关键字保证一个代码块在执行的过程中不会受到其他线程的干扰,这是通过在该代码块的运行过程中对特定的对象加互斥锁来实现的。

2. lock关键字的参数必须是引用类型的对象。lock对基本数据类型如int,long等无效,因为它所作用的类型必须是对象。如果传入long类型数据,势必被转换为int64结构类型,则加锁的是全新的对象引用。如果需要对它们进行互斥访问限制,可以使用system.threading.interlocked类提供的方法,这个类是提供原子操作的。

3. lock(this)的使用要慎重。共有类型中使用lock(this),如果新的对象被创建并加锁,极易造成死锁。

4. 锁定icollection类型对象时,应lock其syncroot属性。

syncroot属性在接口icollection中声明,其实现方式各不相同。

例如在collection(system.collections.objectmodel)中实现如下:

object icollection.syncroot 
{ 
     get 
     { 
          if (this._syncroot == null) 
          { 
               icollection items = this.items as icollection; 
               if (items != null) 
               { 
                    this._syncroot = items.syncroot; 
               } 
               else 
               { 
                    interlocked.compareexchange(ref this._syncroot, new object(), null); 
               } 
          } 
          return this._syncroot; 
     } 
} 

而在list<t>,arraylist等类中实现如下:

object icollection.syncroot 
{ 
     get 
     { 
          if (this._syncroot == null) 
          { 
               interlocked.compareexchange(ref this._syncroot, new object(), null); 
          } 
          return this._syncroot; 
     } 
} 
  

在array类中则直接返回了this:

public object syncroot 
{ 
     get 
     { 
          return this; 
     } 
} 

5. lock关键字是用monitor(管程)类实现的

lock(x) 
{ 
  dosomething(); 
} 

system.object obj = (system.object)x; 
system.threading.monitor.enter(obj); 
try 
{ 
  dosomething(); 
} 
finally 
{ 
  system.threading.monitor.exit(obj); 
} 

以上两段代码是等效的。(msdn)

使用lock关键字相对于monitor类在使用上更简单,也更加保险。