zoukankan      html  css  js  c++  java
  • 多线程下C#如何保证线程安全?

    from:https://www.cnblogs.com/janghe/p/7875093.html

    多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题。所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的。 线程安全问题都是由全局变量及静态变量引起的。

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

    复制代码
    复制代码
     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后,上述代码的执行顺序为下图所示:

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

    水平有限,望各位园友不吝赐教!如果觉得不错,请点击推荐和关注! 
    出处:http://www.cnblogs.com/isaboy/ 
    声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    几种常用的曲线
    0188. Best Time to Buy and Sell Stock IV (H)
    0074. Search a 2D Matrix (M)
    0189. Rotate Array (E)
    0148. Sort List (M)
    0859. Buddy Strings (E)
    0316. Remove Duplicate Letters (M)
    0452. Minimum Number of Arrows to Burst Balloons (M)
    0449. Serialize and Deserialize BST (M)
    0704. Binary Search (E)
  • 原文地址:https://www.cnblogs.com/liuqiyun/p/9103783.html
Copyright © 2011-2022 走看看