多线程下C#如何保证线程安全?
多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题。所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的。 线程安全问题都是由全局变量及静态变量引起的。
为了保证多线程情况下,访问静态变量的安全,可以用锁机制来保证,如下所示:
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#如何保证线程安全?相关推荐
- 单应用下RabbitMQ如何保证线程安全,及多应用下抢数据问题
消费RabbitMQ时的注意事项,如何禁止大量的消息涌到Consumer,保证线程安全: 按照官网提供的订阅型写法(Retrieving Messages By Subscription (" ...
- 分布式环境下,怎么保证线程安全
转:https://blog.csdn.net/Faker_Wang/article/details/80798732 避免并发 在分布式环境中,如果存在并发问题,那么很难通过技术去解决,或者解决的代 ...
- 多线程下的单例模式详解
1. 单例模式 (1) 单例模式简介 (2) 实现方式 ① 饿汉式 ② 懒汉式 2. 多线程下的单例模式 (1) Synchronized (2) 双重检查锁 (3) 双重检查锁+Volatile 补 ...
- volatile不能保证线程安全
对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好起来却不是一件容易的事. 这篇文章将从多个方面来讲解volatile,让你对它更加理解 ...
- python多线程操作列表_详解Python多线程下的list
list 是 Python 常用的几个基本数据类型之一.正常情况下我们会对 list 有增删改查的操作,显然易见不会有任何问题.那么如果我们试着在多线程下操作list 会有问题吗? 多线程下的 lis ...
- 多线程情况下如何保证线程安全
一.线程安全等级 其实线程安全并不是一个"非黑即白"单项选择题.按照"线程安全"的安全程度由强到弱来排序,我们可以将java语言中各种操作共享的数据分为以下5类 ...
- java程序中怎么保证多线程的运行安全_Java线程安全问答(草稿)
1.什么是线程安全? 如果一个类在多线程执行中,在不考虑运行环境的调度干预,也不需要调用代码的协调同步,仍然保证正确地运行,那么这个类就是线程安全的 也就是说,多线程环境下,线程安全的类总是有正确的行 ...
- shiro如何保证session不失效_请问在不加锁的情况下如何保证线程安全?
概念 compare and swap,解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数--内存位置(V).预期原值(A)和新值(B).如果内存位置的值与预期原值相匹配,那么 ...
- 线程基础知识_线程生命周期_从JVM内存结构看多线程下的共享资源
线程生命周期 线程状态 New: 线程创建(new Thread()) Runnable: 线程可运行(thread.start()), 注: 调用start并不一定是运行状态, 可能在等待CPU调度 ...
最新文章
- How to attack a windows domain
- python3 去除列表中重复的元素 保存原来顺序
- [云炬创业管理笔记]第二章测试6
- 今晚直播 | ICML 2021论文解读:基于Cox-MLP模型的二阶段共形预测
- python模拟内置函数all_Python内置all函数详细介绍
- sqlmap md5怎么解密_三十九,hackthebox渗透之DirBuster扫描路径及Sqlmap
- PostgreSQL and SQLAlchemy [ubuntu]
- 牛客练习赛9 F - 珂朵莉的约数
- java中对事件的监听事件,详谈Java中的事件监听机制
- duilib整体框架认识
- matlab里用simulink仿真教程,Matlab-Simulink仿真教程课件.ppt
- Photoshop插件-证件照-白红蓝底-PS插件-脚本开发
- 软件开发团队中各个成员的英文简称
- PDF加密如何解除?教你2个PDF解密方法
- 华为电脑如何投屏到电视linux,华为手机如何投屏到电脑上?手把手教你,无线投屏怎么做...
- Java文件上传同时携带参数
- 腾讯3轮面试都问了Android事件分发,最强技术实现
- CRM项目第一天(2021-12-16)1
- Linux硬盘管理:分区、GParted分区操作
- Android实现开机自动运行程序
热门文章
- Qt Creator操作方法
- OpenGL instancing实例化的实例
- C语言指针与函数传参
- c++11中static类对象构造函数线程安全
- mysql 事务块 sql_Oracle_PL/SQL的基本写法_BEGIN_END块结构及简单的事务实现
- MyCat-Web安装
- 18_Android中Service的生命周期,远程服务,绑定远程服务,aidl服务调用,综合服务案例,编写一个应用程序调用远程支付宝远程服务场景
- maven中去掉单元测试的配置
- 创建一个QT for Android的传感器应用应用程序(摘自笔者2015年将出的《QT5权威指南》,本文为试读篇)
- linux静态分配设备号,Linux驱动开发之静态申请设备号