托管线程池

来源:互联网 发布:apache 网络硬盘 编辑:程序博客网 时间:2024/05/20 06:51

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

Common Language Infrastructure 提供了几种可用来同步对实例和静态成员的访问的策略:

  • 同步代码区域。可以使用 Monitor 类或此类的编译器支持来仅同步需要此类的代码块,从而提高性能。

  • 手动同步。可以使用 .NET Framework 类库提供的同步对象。请参见 同步基元概述,这部分对 Monitor 类进行了讨论。

  • 同步上下文。可以使用 SynchronizationAttributeContextBoundObject 对象启用简单的自动同步。

  • System.Collections.Concurrent 命名空间中的集合类。这些类提供了内置的同步添加和移除操作。有关更多信息,请参见线程安全集合

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

类别

全局字段

静态字段

静态方法

实例字段

实例方法

特定代码块

无同步

同步上下文

同步代码区域

仅当标记时

仅当标记时

仅当标记时

手动同步

手动

手动

手动

手动

手动

手动

无同步

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

手动同步

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

同步代码区域

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

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

说明说明

lockSyncLock 语句是使用 Monitor::EnterMonitor::Exit 实现的,因此,可以在同步区域中将它们与 Monitor 的其他方法一起使用。

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

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

重要说明重要事项

为保护 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 来同步所有实例方法和字段。同一上下文域中的所有对象都共享同一个锁。允许多个线程访问方法和字段,但在任一时刻只允许一个线程访问。

原创粉丝点击