c# – 线程安全Singleton:为什么内存模型不能保证其他线程会看到新实例?

栏目: ASP.NET · 发布时间: 6年前

内容简介:翻译自:https://stackoverflow.com/questions/47816720/thread-safe-singleton-why-the-memory-model-does-not-guarantee-that-the-new-inst

我已经阅读了Jon的Skeet在线页面,了解如何在C#中创建线程安全的Singleton

http://csharpindepth.com/Articles/General/Singleton.aspx

// Bad code! Do not use!
public sealed class Singleton
{
    private static Singleton instance=null;

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            if (instance==null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

在此代码下面的段落中,它说:

As hinted at before, the above is not thread-safe. Two different  threads could both have evaluated the test if (instance==null) and  found it to be true, then both create instances, which violates the  singleton pattern. Note that in fact the instance may already have  been created before the expression is evaluated, but the memory model  doesnt guarantee that the new value of instance will be seen by other  threads unless suitable memory barriers have been passed.

你能否解释为什么内存模型不能保证其他线程可以看到实例的新值?

静态变量位于堆上,但为什么不立即与其他线程共享?我们是否需要等待上下文切换,以便其他线程知道实例不再为空?

Can you please explain why doesnt the memory model does not guarantee that the new value of instance will be seen by other threads?

内存模型很复杂,目前还没有非常清楚地记录,但从根本上来说,很少有情况可以安全地依赖一个线程所写的值,而另一个线程在没有某些锁定或其他线程的情况下被“看到”沟通继续.

例如,考虑一下:

// Bad code, do not use
public class BigLoop
{
    private static bool keepRunning = true;

    public void TightLoop()
    {
        while (keepRunning)
        {
        }
    }

    public void Stop()
    {
        keepRunning = false;
    }
}

如果您创建了两个线程,其中一个调用TightLoop而另一个调用Stop,则无法保证循环方法将终止.

现代CPU中有许多级别的缓存,并且要求每次读取都返回到主内存将消除大量优化.所以我们有内存模型,可以保证哪些变化在什么情况下肯定是可见的.除了这些保证之外,允许JIT编译器假设实际上只有一个线程 – 因此它可以将字段的值缓存在寄存器中,并且永远不会再次访问主存储器,例如.

当前记录的内存模型严重不足,并且表明一些明显奇怪的优化应该是有效的.我不会在那条路上走太远,但是值得阅读Joe Duffy关于 CLR 2.0 memory model 的博客文章.(这比记录的ECMA内存模型更强,但博客文章不是这样一个关键文档的理想位置,我认为还需要更清晰.)

The static variable is located on the heap, but why it is not shared with other threads?

它与其他线程共享 – 但该值不一定立即可见.

翻译自:https://stackoverflow.com/questions/47816720/thread-safe-singleton-why-the-memory-model-does-not-guarantee-that-the-new-inst


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Unity 3D游戏开发(第2版)

Unity 3D游戏开发(第2版)

宣雨松 / 人民邮电出版社 / 2018-9 / 89.00元

Unity 是一款市场占有率非常高的商业游戏引擎,横跨25 个主流游戏平台。本书基于Unity 2018,结合2D 游戏开发和3D 游戏开发的案例,详细介绍了它的方方面面,内容涉及编辑器、游戏脚本、UGUI 游戏界面、动画系统、持久化数据、静态对象、多媒体、资源加载与优化、自动化与打包等。 本书适合初学者或者有一定基础的开发者阅读。一起来看看 《Unity 3D游戏开发(第2版)》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器