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

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

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

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

多线程下C#如何保证线程安全?相关推荐

  1. 单应用下RabbitMQ如何保证线程安全,及多应用下抢数据问题

    消费RabbitMQ时的注意事项,如何禁止大量的消息涌到Consumer,保证线程安全: 按照官网提供的订阅型写法(Retrieving Messages By Subscription (" ...

  2. 分布式环境下,怎么保证线程安全

    转:https://blog.csdn.net/Faker_Wang/article/details/80798732 避免并发 在分布式环境中,如果存在并发问题,那么很难通过技术去解决,或者解决的代 ...

  3. 多线程下的单例模式详解

    1. 单例模式 (1) 单例模式简介 (2) 实现方式 ① 饿汉式 ② 懒汉式 2. 多线程下的单例模式 (1) Synchronized (2) 双重检查锁 (3) 双重检查锁+Volatile 补 ...

  4. volatile不能保证线程安全

    对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好起来却不是一件容易的事. 这篇文章将从多个方面来讲解volatile,让你对它更加理解 ...

  5. python多线程操作列表_详解Python多线程下的list

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

  6. 多线程情况下如何保证线程安全

    一.线程安全等级 其实线程安全并不是一个"非黑即白"单项选择题.按照"线程安全"的安全程度由强到弱来排序,我们可以将java语言中各种操作共享的数据分为以下5类 ...

  7. java程序中怎么保证多线程的运行安全_Java线程安全问答(草稿)

    1.什么是线程安全? 如果一个类在多线程执行中,在不考虑运行环境的调度干预,也不需要调用代码的协调同步,仍然保证正确地运行,那么这个类就是线程安全的 也就是说,多线程环境下,线程安全的类总是有正确的行 ...

  8. shiro如何保证session不失效_请问在不加锁的情况下如何保证线程安全?

    概念 compare and swap,解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数--内存位置(V).预期原值(A)和新值(B).如果内存位置的值与预期原值相匹配,那么 ...

  9. 线程基础知识_线程生命周期_从JVM内存结构看多线程下的共享资源

    线程生命周期 线程状态 New: 线程创建(new Thread()) Runnable: 线程可运行(thread.start()), 注: 调用start并不一定是运行状态, 可能在等待CPU调度 ...

最新文章

  1. How to attack a windows domain
  2. python3 去除列表中重复的元素 保存原来顺序
  3. [云炬创业管理笔记]第二章测试6
  4. 今晚直播 | ICML 2021论文解读:基于Cox-MLP模型的二阶段共形预测
  5. python模拟内置函数all_Python内置all函数详细介绍
  6. sqlmap md5怎么解密_三十九,hackthebox渗透之DirBuster扫描路径及Sqlmap
  7. PostgreSQL and SQLAlchemy [ubuntu]
  8. 牛客练习赛9 F - 珂朵莉的约数
  9. java中对事件的监听事件,详谈Java中的事件监听机制
  10. duilib整体框架认识
  11. matlab里用simulink仿真教程,Matlab-Simulink仿真教程课件.ppt
  12. Photoshop插件-证件照-白红蓝底-PS插件-脚本开发
  13. 软件开发团队中各个成员的英文简称
  14. PDF加密如何解除?教你2个PDF解密方法
  15. 华为电脑如何投屏到电视linux,华为手机如何投屏到电脑上?手把手教你,无线投屏怎么做...
  16. Java文件上传同时携带参数
  17. 腾讯3轮面试都问了Android事件分发,最强技术实现
  18. CRM项目第一天(2021-12-16)1
  19. Linux硬盘管理:分区、GParted分区操作
  20. Android实现开机自动运行程序

热门文章

  1. Qt Creator操作方法
  2. OpenGL instancing实例化的实例
  3. C语言指针与函数传参
  4. c++11中static类对象构造函数线程安全
  5. mysql 事务块 sql_Oracle_PL/SQL的基本写法_BEGIN_END块结构及简单的事务实现
  6. MyCat-Web安装
  7. 18_Android中Service的生命周期,远程服务,绑定远程服务,aidl服务调用,综合服务案例,编写一个应用程序调用远程支付宝远程服务场景
  8. maven中去掉单元测试的配置
  9. 创建一个QT for Android的传感器应用应用程序(摘自笔者2015年将出的《QT5权威指南》,本文为试读篇)
  10. linux静态分配设备号,Linux驱动开发之静态申请设备号