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

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

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

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

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

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

多线程下C#如何保证线程安全?的更多相关文章

  1. ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开

    ASP.NET MVC Filters 4种默认过滤器的使用[附示例]   过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响 ...

  2. 多线程下,两个线程交替打印0 -100,使用wait()和notify()

    多线程下,两个线程交替打印0 -100,使用wait()和notify() public class ThreadTest{ private static final Object lock = ne ...

  3. C#多线程(下) 分类: C# 线程 2015-03-09 10:41 153人阅读 评论(0) 收藏

    四.多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPool(线 ...

  4. java 单例的实现及多线程下的安全

    package com.demo01; public class Single { /** * 设计模式:单例设计模式 * 解决一个类中只允许存在一个对象这种情况: * 不允许通过类,无限制的创建该类 ...

  5. Linux多线程(二)(线程等待,退出)

    1. 线程的等待退出 1.1. 等待线程退出 线程从入口点函数自然返回,或者主动调用pthread_exit()函数,都可以让线程正常终止 线程从入口点函数自然返回时,函数返回值可以被其它线程用pth ...

  6. 多线程下的list

    前言 list 是 Python 常用的几个基本数据类型之一.正常情况下我们会对 list 有增删改查的操作,显然易见不会有任何问题.那么如果我们试着在多线程下操作list 会有问题吗? 多线程下的 ...

  7. C#多线程下如何保证线程安全?

    多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题.所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是 ...

  8. Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%。再往后,每提高0.1%,优化难度成指数级增长了。哪怕是千分之一,也直接影响用户体验,影响每天上万张机票的销售额。 在高并发场景下,提供了保证线程安全的对象、方法。比如经典的ConcurrentHashMap,它比起HashMap,有更小粒度的锁,并发读写性能更好。线程安全的StringBuilder取代S

    Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%.再往后,每提高0.1%,优化难度成指数级增长了.哪怕是千分之一,也直接影响用户体验,影响每天上万张机 ...

  9. 第10章 线程控制(5)_多线程下的fork

    6. 线程和fork 6.1 多线程下的fork (1)历史包袱 ①fork与多线程的协作性很差,这是POSIX系统操作系统的历史包袱. ②长期以来程序都是单线程的,fork运行正常,但引入线程这后, ...

随机推荐

  1. 仿Java的AtomicMarkableReference的AtomicMarkablePointer(C++)

    //@author: Zou Xiaohang //@describe: this class is like AtomicMarkableReference which is in java con ...

  2. JSP网站开发基础总结《三》

    经过前两篇的总结,我想大家一定迫不及待的想学习今天的关于jsp与mysql的数据库连接的知识了.既然需要连接mysql数据库,你首先需要保证你的电脑已经安装过mysql数据库,mysql数据库的安装步 ...

  3. hdu3339 In Action(Dijkstra+01背包)

    /* 题意:有 n 个站点(编号1...n),每一个站点都有一个能量值,为了不让这些能量值连接起来,要用 坦克占领这个站点!已知站点的 之间的距离,每个坦克从0点出发到某一个站点,1 unit dis ...

  4. Java多线程系列--“基础篇”09之 interrupt()和线程终止方式

    概要 本章,会对线程的interrupt()中断和终止方式进行介绍.涉及到的内容包括:1. interrupt()说明2. 终止线程的方式2.1 终止处于“阻塞状态”的线程2.2 终止处于“运行状态” ...

  5. JavaScript及兼容性笔记

    1. Json to String JSON.stringify(jsonobj)//(IE8+,Chrome 1+,FF 3+) //参考 http://www.nowamagic.net/libr ...

  6. 测试servlet学习笔记

    操作方法: 1.新建工程: File——>new——>Java Project——>TestServlet(工程名称)——>Finish. 2.加载servlet-api.ja ...

  7. 多个ajax请求下等待条显示和隐藏的简单处理

    处理为遇到ajax请求就显示等待条,直到所有的ajax请求执行完毕才关闭等待条.比较简单,源码如下(基于jQuery) //基于jQuery //从第一个ajax请求发出开始显示等待条?直到一系列aj ...

  8. 大话immutable.js

    为啥要用immutable.js呢.毫不夸张的说.有了immutable.js(当然也有其他实现库)..才能将react的性能发挥到极致!要是各位看官用过一段时间的react,而没有用immutabl ...

  9. 检测WCF服务是否在线(动态执行WCF服务)

    在我们的系统里有多个wcf支撑.但是有的时候会莫名的停止,于是今天写了一个服务,定时去检测其他wcf服务是否在线.那么最简单的办法自然是引用其他wcf服务让vs给我们自动生成clientProxy然后 ...

  10. [译]学习IPython进行交互式计算和数据可视化(一)

    --学习IPython进行交互式Python编程.高性能数字计算和数据可视化 作者:Cyrille Rossant 译者:Tacey Wong 注:仅为个人翻译及学习,多有谬处,E文尚可的推荐阅读英文 ...