浅议“全局变量”、“多线程”和“编译器陷阱”

简介:
今天偶然看到一段代码,也看到了作者对此的说明,觉得很有意思:
public event  EventHandler Started;

protected virtual void  OnStarted(EventArgs e)
{
    EventHandler handler 
=  Started;
    
if  (handler  !=  null )
    {
        handler(
null , e);
    }
}

为什么要申明一个全局的事件变量 Started?一开始我也觉得很多余,后来听作者说这段代码可以用到多线程中,有可能正在判断事件变量Started的时候,它有可能被另外的一个线程给改变了,这里引入一个局部变量 handler,可以保留Started之前的对象引用,确保后面的事件能够得到正确的处理。

那么我们是否可以按照这个风格写下面类似的代码呢?

public object MyObject;

public  void OnFunction()
{
    object obj
= MyObject;
    
if (obj!= null)
    {
        //在这里对obj进行其它处理

    }
}

上面这段代码在一般情况下没有问题,在多线程下面也工作良好,但如果你启用了编译器优化,很不幸,这段代码被优化成了下面的样子:

public object MyObject;

public  void OnFunction()
{
   
 if (MyObject!= null)
    {
        //在这里对MyObject进行其它处理

    }
}

也就是说,MyObject 对象引用的代码被inline(内联)了,取消了局部变量object obj的定义,减少了对象数量和创建过程,有助于提高效率,如果这段代码被用于多线程中,噩梦很可能就来了,你不知道是谁修改了MyObject的值,这就是“编译器陷阱”!

类似的代码,为什么上面EventHandler Started 在多线程下工作的很好,而object MyObject 却不可以?原来,这其中有玄机,在.NET平台中,它采用了不同的优化策略,参加原博文中的说法:

如果我说,这样的代码明显是会被编译器优化掉的,因此这样写完全没有意义,怎样呢?毕竟EventHandler作为一个委托,并没有用volatile关键字声明(事实上事件不能声明为volatile,但可以在这里用Thread.VolatileRead(ref object)方法),使用时也没有用Interlocked来访问。我其实真没有想到那么远,不过CLR Via C#上给出了解释(记不得是哪一章了):JIT的编译器在这里会识别出这个写法并且确保不会把handler变量优化掉。真是万幸,但估计又成为了一个被学院派的诟病的特性。

原文地址:

再说说C#定义事件的写法



    本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/archive/2012/01/20/2328036.html,如需转载请自行联系原作者

相关文章
|
6月前
|
缓存 安全 Java
为什么全局变量可能成为多线程环境中的安全隐患
为什么全局变量可能成为多线程环境中的安全隐患
|
6月前
|
API
线程私有存储空间的全局变量pthread_key_t
线程私有存储空间的全局变量pthread_key_t
127 0
|
安全 调度 Python
【从零学习python 】80.线程访问全局变量与线程安全问题
【从零学习python 】80.线程访问全局变量与线程安全问题
103 0
|
安全 Python
【从零学习python 】79. 线程访问全局变量与线程安全问题
【从零学习python 】79. 线程访问全局变量与线程安全问题
84 0
|
NoSQL 安全 Java
案例15-ArrayList线程不安全,共用全局变量导致数据错乱问题,占用内存情况
案例15-ArrayList线程不安全,共用全局变量导致数据错乱问题,占用内存情况
|
Python
【Python零基础入门篇 · 32】:资源共享、全局变量和资源竞争,线程的同步,执行的任务有参数
【Python零基础入门篇 · 32】:资源共享、全局变量和资源竞争,线程的同步,执行的任务有参数
134 0
【Python零基础入门篇 · 32】:资源共享、全局变量和资源竞争,线程的同步,执行的任务有参数
|
索引 Python
python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(2)
python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(2)
144 0
python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(2)
|
存储 JSON 资源调度
python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(1)
线程(英语:thread)是操作系统能够进行运算调度的最小单位。线程很重要,通过本篇文章可以让你们很好的了解线程的传参、线程执行规则、守护主线程、线程间共享全局变量、进程互斥锁、死锁进程怎么解决。希望对你们有所帮助。
233 0
python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(1)
|
开发者 Python
多线程共享全局变量&线程安全问题| 学习笔记
快速学习多线程共享全局变量&线程安全问题
|
安全 调度 Python
3_python高阶_线程—多线程-共享全局变量
python高阶_线程—多线程-共享全局变量
287 0