• ASP.NET中的多线程安全问题
  • Holly 发表于 2016/2/18 11:41:00 | 分类标签: 多线程 超线程 线程安全
  • 多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题。所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的。 线程安全问题都是由全局变量及静态变量引起的。

    为了保证多线程情况下,访问静态变量的安全,可以用锁机制来保证,如下所示:

     1         //需要加锁的静态全局变量
     2         private static bool _isOK = false;
     3         //lock只能锁定一个引用类型变量
     4         private static object _lock = new object();
     5         static void MLock()
     6         {
     7             //多线程
     8             new System.Threading.Thread(Done).Start();
     9             new System.Threading.Thread(Done).Start();
    10             Console.ReadLine();
    11         }
    12 
    13         static void Done()
    14         {
    15             //lock只能锁定一个引用类型变量
    16             lock (_lock)
    17             {
    18                 if (!_isOK)
    19                 {
    20                     Console.WriteLine("OK");
    21                     _isOK = true;
    22                 }
    23             }
    24         } 

    需要注意的是,Lock只能锁住一个引用类型的对象。另外,除了锁机制外,高版本的C#中加入了async和await方法来保证线程安全,如下所示:

     1 public static class AsynAndAwait
     2  {
     3         //step 1 
     4         private static int count = 0;
     5         //用async和await保证多线程下静态变量count安全
     6         public async static void M1()
     7         {
     8             //async and await将多个线程进行串行处理
     9             //等到await之后的语句执行完成后
    10             //才执行本线程的其他语句
    11             //step 2
    12             await Task.Run(new Action(M2));
    13             Console.WriteLine("Current Thread ID is {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
    14             //step 6
    15             count++;
    16             //step 7
    17             Console.WriteLine("M1 Step is {0}", count);
    18         }
    19 
    20         public static void M2()
    21         {
    22             Console.WriteLine("Current Thread ID is {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
    23             //step 3
    24             System.Threading.Thread.Sleep(3000);
    25             //step 4
    26             count++;
    27             //step 5
    28             Console.WriteLine("M2 Step is {0}", count);
    29         }
    30 }

    在时序图中我们可以知道,共有两个线程进行交互,如下图所示:

    用async和await后,上述代码的执行顺序为下图所示:

     

    若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时对一个变量执行读写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:Holly
  • 加入时间:2013/5/15 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮