为多线程处理同步数据(包括实例和静态成员)

为多线程处理同步数据

https://msdn.microsoft.com/zh-cn/library/z8chs7ft(VS.80).aspx

.NET Framework 2.0             
 

当多个线程可以调用单个对象的属性和方法时,对这些调用进行同步处理是非常重要的。否则,一个线程可能会中断另一个线程正在执行的任务,使该对象处于一种无效状态。其成员不受这类中断影响的类叫做线程安全类。

“公共语言基础结构”提供了几种可用来同步对实例和静态成员的访问的策略: 

公共语言运行库提供一个线程模型,在该模型中,类分为许多类别,这些类别可以根据要求以各种不同的方式进行同步。下表显示了为具有给定同步类别的字段和方法提供的同步支持。

 
类别          全局字段          静态字段          静态方法          实例字段          实例方法          特定代码块          

无同步

同步上下文

同步代码区域

仅当标记时

仅当标记时

仅当标记时

手动同步

手动

手动

手动

手动

手动

手动

无同步

这对于对象是默认情况。任何线程都可以随时访问任何方法或字段。一次只能有一个线程访问这些对象。

手动同步

.NET Framework 类库提供大量用于同步线程的类。请参见同步基元概述

同步代码区域

可以使用 Monitor 类或编译器关键字来同步代码块、实例方法和静态方法。不支持同步静态字段。

Visual Basic 和 C# 都支持使用特定语言关键字标记代码块,在 C# 中使用的是 lock 语句,在 Visual Basic 中使用的是 SyncLock 语句。当由线程执行该代码时,会尝试获取锁。如果该锁已由其他线程获取,则在锁变为可用状态之前,该线程一直处于禁止状态。当线程退出同步代码块时,锁就会被释放,它与线程的退出方式无关。

Note注意

lockSyncLock 语句是使用 System.Threading.Monitor.Enter(System.Object)System.Threading.Monitor.Exit(System.Object) 实现的,因此,可以在同步区域中将它们与 Monitor 的其他方法一起使用。

还可以用使用 MethodImplAttribute MethodImplOptions.Synchronized 修饰方法,其效果和使用 Monitor 或其中一个编译器关键字锁定整个方法体相同。

Thread.Interrupt 可用于使线程跳出阻止操作(如等待访问同步代码区域)。Thread.Interrupt 还用于使线程跳出 Thread.Sleep 等操作。

Note要点

为保护 static 方法(Visual Basic 中的 Shared 方法),请不要锁定类型,即:C# 中的 typeof(MyType)、Visual Basic 中的 GetType(MyType) 或 C++ 中的 MyType::typeid。而应改用私有静态对象。类似地,不要使用 C# 中的 this(Visual Basic 中的 Me)锁定实例方法。而应使用私有对象。类或实例可由其他代码锁定,您自己的代码进行锁定可能会引起死锁或性能问题。

编译器支持

Visual Basic 和 C# 都支持使用 Monitor.EnterMonitor.Exit 来锁定对象的语言关键字。Visual Basic 支持 SyncLock 语句;C# 支持 lock 语句。

这两种情况下,如果代码块中引发异常,则 lockSyncLock 锁获取的锁将自动释放。C# 和 Visual Basic 编译器在发出 try/finally 块时,在 try 的起始处使用 Monitor.Enter,在 finally 块中使用 Monitor.Exit。如果 lockSyncLock 块内部引发了异常,则会运行 finally 处理程序,从而使您可以执行任何清除工作。

同步上下文

可以使用任何 ContextBoundObject SynchronizationAttribute 来同步所有实例方法和字段。同一上下文域中的所有对象都共享同一个锁。允许多个线程访问方法和字段,但在任一时刻只允许一个线程访问。

posted on 2015-03-12 16:23  NLazyo  阅读(596)  评论(0编辑  收藏  举报