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  doesn’t 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 doesn’t 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


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

查看所有标签

猜你喜欢:

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

代码之髓

代码之髓

[日] 西尾泰和 / 曾一鸣 / 人民邮电出版社 / 2014-8 / 45.00元

《代码之髓:编程语言核心概念》作者从编程语言设计的角度出发,围绕语言中共通或特有的核心概念,通过语言演变过程中的纵向比较和在多门语言中的横向比较,清晰地呈现了程序设计语言中函数、类型、作用域、类、继承等核心知识。本书旨在帮助读者更好地理解各种概念是因何而起,并在此基础上更好地判断为何使用、何时使用及怎样使用。同时,在阅读本书后,读者对今后不断出现的新概念的理解能力也将得到提升。 《代码之髓:......一起来看看 《代码之髓》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具