随笔 - 547  文章 - 213 评论 - 417 阅读 - 107万

下面的规则概括了实现线程处理的设计指南:

  • 避免提供改变静态状态的静态方法。在通用服务器方案中,静态状态在请求间共享,这意味着多个线程可以同时执行该代码。这造成了产生线程处理错误的可能性。考虑使用将数据封装为不在请求间共享的实例的设计方案。
  • 静态状态必须是线程安全的。
  • 实例状态不必是线程安全的。默认情况下,类库应该不应是线程安全的。用添加锁的方法创建线程安全代码会降低性能、增加锁争用和造成发生死锁错误的可能性。在通用应用程序模型中,一次只有一个线程执行用户代码,这使线程安全需要减为最小。因此,.NET Framework 类库在默认情况下不是线程安全的。如果希望提供线程安全的版本,请提供返回类型的线程安全实例的静态 Synchronized 方法。有关示例,请参见 System.Collections.ArrayList.Synchronized 方法System.Collections.ArrayList.IsSynchronized 方法 (此处需要深入研究一下)
  • 在设计库时考虑服务器方案中的运行压力。尽可能避免使用锁。
  • 注意锁定部分中的方法调用。当 A 类中的静态方法调用 B 类中的静态方法时会导致死锁,反之亦然。如果 A 和 B 都同步它们的静态方法,这将导致死锁。可能只有在沉重的线程处理压力下才会发现此死锁(此处需要深入研究一下)
  • 当 A 类中的静态方法调用 A 类中的静态方法时会导致性能问题。如果这些方法未被正确分解,由于将有大量的冗余同步,因此性能将遭受损失。过度使用粒度同步可能会对性能造成负面影响。另外,它对可缩放性可能有严重的负面影响。
  • 注意 lock 语句(在 Visual Basic 中为 SyncLock)的问题。您可能会想用 lock 语句解决所有线程处理问题。但是,对于必须是原子性的更新来说,System.Threading.Interlocked 类具有优先权如果没有争用,它执行单个 lock 前缀。在代码检查中,应该注意检查有没有下面的示例中所展示的这类实例。
    [Visual Basic]
    SyncLock Me
       myField 
    += 1
    End SyncLock

    [C#]
    lock(this
    {
       myField
    ++;
    }

    如果使用以下示例替换上一个示例,则可以提高性能。

    [Visual Basic]
    System.Threading.Interlocked.Increment(myField)

    [C#]
    System.Threading.Interlocked.Increment(myField);

    另一个示例仅在对象类型变量为空(在 Visual Basic 中为 Nothing)时,才更新该对象类型变量。可以使用以下代码更新变量,并使代码成为线程安全的。

    [Visual Basic]
    If x Is Nothing Then
       SyncLock Me
          If x Is Nothing Then
             x 
    = y
          End If
       End SyncLock
    End If

    [C#]
    if (x == null)
    {
       
    lock (this)
       {
          
    if (x == null)
          {
             x 
    = y;
          }
       }
    }

    通过将上一个示例替换为以下代码,可以提高性能。

    [Visual Basic]
    System.Threading.Interlocked.CompareExchange(x, y, Nothing)

    [C#]
    System.Threading.Interlocked.CompareExchange(
    ref x, y, null);

  • 尽可能避免同步需要。对于高通信量,最好避免同步。有时可以调整算法以忍受争用状况而不是消除它们。


相关知识:

1. ArrayList.Synchronized 方法


返回同步(线程安全)的列表包装。


重载列表

1. 返回同步(线程安全)的 ArrayList 包装。受 .NET Framework 精简版的支持。

     [C#] public static ArrayList Synchronized(ArrayList);

2. 返回同步(线程安全)的 IList 包装。

    [C#] public static IList Synchronized(IList);

示例

以下示例显示如何同步 ArrayList、如何确定 ArrayList 是否同步以及如何使用同步的 ArrayList

[C#] 
using System;
using System.Collections;
public class SamplesArrayList  {

   
public static void Main()  {

      
// Creates and initializes a new ArrayList.
      ArrayList myAL = new ArrayList();
      myAL.Add( 
"The" );
      myAL.Add( 
"quick" );
      myAL.Add( 
"brown" );
      myAL.Add( 
"fox" );

      
// Creates a synchronized wrapper around the ArrayList.
      ArrayList mySyncdAL = ArrayList.Synchronized( myAL );

      
// Displays the sychronization status of both ArrayLists.
      Console.WriteLine( "myAL is {0}.", myAL.IsSynchronized ? "synchronized" : "not synchronized" );
      Console.WriteLine( 
"mySyncdAL is {0}.", mySyncdAL.IsSynchronized ? "synchronized" : "not synchronized" );
   }
}
/* 
This code produces the following output.

myAL is not synchronized.
mySyncdAL is synchronized.
*/

那么同步以后的ArrayList和没有同步的ArrayList有何不同那?请看下面:



2. ArrayList.IsSynchronized 属性

获取一个值,该值指示对 ArrayList 的访问是否同步(线程安全)。

[C#]
public virtual bool IsSynchronized {get;}
属性值
如果对 ArrayList 的访问是同步(线程安全)的,则为 true;否则为 false。默认为 false。
实现
ICollection.IsSynchronized
备注
若要保证 ArrayList 的线程安全,则必须通过由 Synchronized 方法返回的包装来执行所有操作。
通过集合枚举在本质上不是一个线程安全的过程。甚至在对集合进行同步处理时,其他线程仍可以修改该集合,这会导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。
[Visual Basic, C#] 下面的代码示例显示如何在整个枚举过程中使用 SyncRoot 锁定集合:
[C#] 
ArrayList myCollection 
= new ArrayList();
 
lock( myCollection.SyncRoot ) {
 
foreach ( Object item in myCollection ) {
 
// Insert your code here.
 }
}




至此,真相大白,原来“同步”就是“线程安全”的意思
比如:
如果对 ArrayList 的访问是同步(线程安全)的,则为 true;否则为 false。默认为 false。


但是,下面的这句话同步应该怎么理解那?







注意锁定部分中的方法调用。当 A 类中的静态方法调用 B 类中的静态方法时会导致死锁,反之亦然。
如果 A 和 B 都同步它们的静态方法,这将导致死锁。可能只有在沉重的线程处理压力下才会发现此死锁。



















posted on   今夜太冷  阅读(825)  评论(2编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示