title: Is it correct to perform regular reads on a field lazily-initialized by Interlocked.CompareExchange?
body: <p>Suppose you have a property <code>public Foo Bar { get; }</code> that you want to lazily initialize. One such approach might be to use the <code>Interlocked</code> class, which guarantees atomicity for certain sequences of operations (e.g. incrementing, adding, compare-exchange). You could do this:</p>
  
  <pre><code>private Foo _bar;
  
  public Foo Bar
  {
      get
      {
          // Initial check, necessary so we don't call new Foo() every time when invoking the method
          if (_bar == null)
          {
              // In the unlikely case 2 threads come in here
              // at the same time, new Foo() will simply be called
              // twice, but only one of them will be set to _bar
              Interlocked.CompareExchange(ref _bar, new Foo(), null);
          }
          return _bar;
      }
  }
  </code></pre>
  
  <p>There are many places that demonstrate this approach to lazy initialization, e.g. <a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2012/09/06/c.net-little-wonders-interlocked-compareexchange.aspx" rel="nofollow noreferrer">this blog</a> and <a href="https://github.com/dotnet/corefx/blob/master/src/System.Collections/src/System/Collections/Generic/Queue.cs#L81" rel="nofollow noreferrer">places in the .NET Framework itself</a>.</p>
  
  <p>My question is, shouldn't the read from <code>_bar</code> be volatile? For example Thread 1 could have called <code>CompareExchange</code>, setting the value of <code>_bar</code>, but that change wouldn't be visible to Thread 2 since (if I understand <a href="https://stackoverflow.com/questions/72275/when-should-the-volatile-keyword-be-used-in-c">this question</a> correctly) it may have cached the value of <code>_bar</code> as null, and it may end up calling <code>Interlocked.CompareExchange</code> again, despite the fact that Thread 1 already set <code>_bar</code>. So shouldn't <code>_bar</code> be marked volatile, to prevent this from happening?</p>
  
  <p>In short, is <a href="https://github.com/dotnet/corefx/blob/master/src/System.Collections/src/System/Collections/Generic/Queue.cs#L81" rel="nofollow noreferrer">this approach</a> or <a href="https://github.com/dotnet/corefx/blob/master/src/System.Buffers/src/System/Buffers/ArrayPool.cs#L39-L51" rel="nofollow noreferrer">this approach</a> to lazy initialization correct? Why is <code>Volatile.Read</code> (which has the same effect as marking a variable volatile and reading from it) used in one case, but not the other?</p>
  
  <p><strong>edit TL;DR:</strong> If one thread updates the value of a field via <code>Interlocked.CompareExchange</code>, will that updated value be immediately visible to other threads performing non-volatile reads of the field?</p>