对于需要双volatile修饰符检查锁定在.NET中 [英] The need for volatile modifier in double checked locking in .NET

查看:129
本文介绍了对于需要双volatile修饰符检查锁定在.NET中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多文说,实施.NET双重检查锁定,当你锁定在球场上应该应用volatile修饰符。但是,到底为什么?考虑下面的例子:

Multiple texts say that when implementing double-checked locking in .NET the field you are locking on should have volatile modifier applied. But why exactly? Considering the following example:

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

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

         return instance;
      }
   }
}

为什么不锁(SyncRoot上)完成必要的内存一致性?是不是真的,经过锁定语句读取和写入会挥发,因此必要的一致性会实现呢?

why doesn't "lock (syncRoot)" accomplish the necessary memory consistency? Isn't it true that after "lock" statement both read and write would be volatile and so the necessary consistency would be accomplished?

推荐答案

挥发性是不必要的。嗯,有点**

Volatile is unnecessary. Well, sort of**

挥发性用于创建一个内存屏障*之间读取和可变写道。结果
锁定,使用时,会导致各地块创建里面的内存屏障锁,除了限制访问该块一个线程。结果
记忆障碍,使它所以每个线程读取变量(而不是在某个寄存器缓存本地值)的最大电流值,编译器不会重新排序的语句。使用挥发性是不必要的,因为**你已经有了一个锁。

volatile is used to create a memory barrier* between reads and writes on the variable.
lock, when used, causes memory barriers to be created around the block inside the lock, in addition to limiting access to the block to one thread.
Memory barriers make it so each thread reads the most current value of the variable (not a local value cached in some register) and that the compiler doesn't reorder statements. Using volatile is unnecessary** because you've already got a lock.

约瑟夫阿尔巴哈利解释这个东西的方式比我以往任何时候都可以。

Joseph Albahari explains this stuff way better than I ever could.

和一定要检查出乔恩斯基特的指南,在C#

And be sure to check out Jon Skeet's guide to implementing the singleton in C#

结果
更新:结果
* 挥发性导致变量的读取为 VolatileRead 和写入是 VolatileWrite s,这在x86和x64上的CLR,都与一个内存屏障实施。它们可以细粒上的其他系统。


update:
*volatile causes reads of the variable to be VolatileReads and writes to be VolatileWrites, which on x86 and x64 on CLR, are implemented with a MemoryBarrier. They may be finer grained on other systems.

**我的回答如果你正在使用的x86和x64处理器的CLR是唯一正确的。它的可能的是在其他内存模型真实,就像单声道(及其他实现),Itanium64和未来的硬件。这就是乔恩是指在他的文章中的​​陷阱双检查锁定。

**my answer is only correct if you are using the CLR on x86 and x64 processors. It might be true in other memory models, like on Mono (and other implementations), Itanium64 and future hardware. This is what Jon is referring to in his article in the "gotchas" for double checked locking.

做的一个{标记变量挥发性 Thread.VolatileRead 阅读它,或插入电话到 Thread.MemoryBarrier }可能为code到处于弱势的内存模型情况正常工作是必要的。

Doing one of {marking the variable as volatile, reading it with Thread.VolatileRead, or inserting a call to Thread.MemoryBarrier} might be necessary for the code to work properly in a weak memory model situation.

据我了解,在CLR(即使在IA64),写永远不会重新排序(总是写有释放的语义)。然而,IA64,读取可能会重新排序来以前写的,除非它们被标记不稳定。 Unfortuantely,我没有获得IA64硬件一起玩,所以什么我说一下这将是炒作。

From what I understand, on the CLR (even on IA64), writes are never reordered (writes always have release semantics). However, on IA64, reads may be reordered to come before writes, unless they are marked volatile. Unfortuantely, I do not have access to IA64 hardware to play with, so anything I say about it would be speculation.

我还发现这些文章有所帮助:搜索
<一href=\"http://www.$c$cproject.com/KB/tips/MemoryBarrier.aspx\">http://www.$c$cproject.com/KB/tips/MemoryBarrier.aspx


万斯·莫里森的文章(一切都指向这一点,它谈论双重检查锁定)结果
克里斯brumme的文章(一切链接到本)结果
<一href=\"http://www.bluebytesoftware.com/blog/PermaLink,guid,543d89ad-8d57-4a51-b7c9-a821e3992bf6.aspx\">Joe达菲:双残破的变体检查锁定

i've also found these articles helpful:
http://www.codeproject.com/KB/tips/MemoryBarrier.aspx
vance morrison's article (everything links to this, it talks about double checked locking)
chris brumme's article (everything links to this)
Joe Duffy: Broken Variants of Double Checked Locking

路易斯·阿伯对多线程给予的概念很好的概述太结果系列
<一href=\"http://msmvps.com/blogs/luisabreu/archive/2009/06/29/multithreading-load-and-store-reordering.aspx\">http://msmvps.com/blogs/luisabreu/archive/2009/06/29/multithreading-load-and-store-reordering.aspx

<一href=\"http://msmvps.com/blogs/luisabreu/archive/2009/07/03/multithreading-introducing-memory-fences.aspx\">http://msmvps.com/blogs/luisabreu/archive/2009/07/03/multithreading-introducing-memory-fences.aspx

luis abreu's series on multithreading give a nice overview of the concepts too
http://msmvps.com/blogs/luisabreu/archive/2009/06/29/multithreading-load-and-store-reordering.aspx
http://msmvps.com/blogs/luisabreu/archive/2009/07/03/multithreading-introducing-memory-fences.aspx

这篇关于对于需要双volatile修饰符检查锁定在.NET中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆