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

摘要:
线程安全问题是由全局变量和静态变量引起的。1//要锁定的静态全局变量2privatestaticPool isOK=false;3//lock只能锁定一个引用类型变量locked_lock=newobject();11} 1213 staticvoidDone()14{15//lock只有一个引用类型变量16lock(_lock)17{18if(!

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

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

 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 }

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

多线程下C#如何保证线程安全?第1张

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

多线程下C#如何保证线程安全?第2张

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

免责声明:文章转载自《多线程下C#如何保证线程安全?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【知识点】树链剖分数据挖掘:基于Spark+HanLP实现影视评论关键词抽取(1)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Eclipse debug 多线程

      以前用到过许多线程开发,对多线程开发也算是小有点心得,但一开始多线程开发的时候,碰到很多壁。但总得来说,有个好的工具总是能事半功倍。我用的工具是eclipse,在开发多线程时,其debug模式是能直接模拟多线程环境的,网上也有许多资料,但大多都不是很全。希望我能够将自己的一些心得记录下来,希望能帮助到还为多线程开发而纠结的朋友。 先写个简单的...

SQL中declare变量的作用域(续)一些问题

在上次讨论了declare变量的作用域以后我们继续深入谈论一下,准确的说是我有些疑惑想跟大家讨论,有高手明白的话指点一下。 关于作用域的谈论:http://www.cnblogs.com/breezeli/archive/2010/04/16/1713308.html 这个问题不太好解释,大家看一段代码,在循环中定义表变量。 注意 代码使用Northw...

Linux用户环境变量及操作

一、环境变量 用户登录Linux系统后,操作系统会自动配置好工作环境-语言、家目录、邮箱目录、命令搜索路径、终端类型、用户名、命令提示符等。用户的工作环境由一系列的环境变量定义。格式如下: 环境变量名=值 环境变量由大小写字母、数字、_、组成,一般大写。 常见的用户环境变量: LANG=zh_CN.UTF-8,语言定义为UTF-8 HOMS=/home/z...

linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

Linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量、信号量和读写锁。 下面是思维导图:  一、互斥锁(mutex)   锁机制是同一时刻只允许一个线程执行一个关键部分的代码。 1 . 初始化锁 int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t...

深度剖析OpenGL ES中的多线程和多窗口渲染技术

由 创新网小编 于 星期五, 2014-04-11 14:56 发表 移动设备中的CPU和GPU已经变得很强大,到处都是配备一个或多个高分辨率屏幕的设备,需要使用带有图形驱动器的复杂交互也日益增加。在这篇博客文章中,我将讨论多线程和多窗口渲染对开发人员来讲意味着什么,同时我将介绍将这些技术应用您设计当中的条件和时机。 什么是多线程渲染? 传统上,Ope...

Python基础-多线程与多进程

一,线程与进程之间的关系:(从知乎上看到的) 一个必须知道的事实:执行一段程序代码,实现一个功能的过程介绍 ,当得到CPU的时候,相关的资源必须也已经就位,就是显卡啊,GPS啊什么的必须就位,然后CPU开始执行。这里除了CPU以外所有的就构成了这个程序的执行环境,也就是我们所定义的程序上下文。当这个程序执行完了,或者分配给他的CPU执行时间用完了,那它就...