Multithreading: using VolatileXXX instead of the volatile keyword

Published Mon, Jul 6 2009 21:25

[Update: Brad detected a flaw in the code: I had forgotten to initialize the _initialized field. Thanks!]

[Update2: Brad detected another flaw in the code: return _instance must be outside the if. Thanks!]

In the previous post we’ve seen how we can use the C# volatile keyword to guarantee that those nasty load-load reordering stay away from our code. As I’ve said before, we can also use the static Thread.VolatileRead or Thread.VolatileWrite for having more control over the way fences are applied to our code. Going back to our previous volatile example, the question is: do we really need a fence whenever we access our instance variable?

Looking at the code, I guess that we can get  away by just using an acquire fence on the initialization of the instance. Recall that an acquire fence is an optimization of the full fence and ensures that no load or store that comes after the fence can be moved before the fence (it’s just what we need to ensure proper initialization and eliminate the possible load/load reorderings allowed by the CLR).

With this in mind, lets update our sample, ok? Btw, we’ll be using another variable for controlling initialization (we’re picking an integer). This is your best option for initializing value types since you can’t control it size or check it for null (don’t forget our previous discussion on word size, alignment and .NET). Here’s the final code:

class Lazy{
  private Object _locker = new Object();
  private SomeObject _instance = null;
  private Int32 _initialized = 0;
  public SomeObject SomeObject {
    get {
      if (Thread.VolatileRead(ref _initialized) == 0) {
        lock (_locker) {
          if (_initialized == 0) {
            _instance = new SomeObject();
_initialized = 1; } }
}
return _instance; } } }

This code is also correct and will behave properly in all the current architectures that run Windows and the CLR. There’s no need for running another VolatileRead on the inner comparison due to a thing called control dependency (check this post by Joe Duffy for more info). Notice that in these posts our main objective is ensuring that you end up getting only one instance of a specific type. As I’ve said, if you don’t care about creating multiple instances and only need to ensure that you’ll have only one active instance, you can only use the Interlocked.CompareExchange method for that. We’ll see how in the next post. Keep tuned!

Filed under: ,

Comments

# Brad said on Monday, July 06, 2009 7:25 PM

These articles are fantastic! I only discovered this site yesterday, so I have a lot of catching up and backreading to do.

Thank you very much!

# Brad said on Monday, July 06, 2009 7:59 PM

One quick question, where does the value of _initialized change from 0?

# Brad said on Sunday, July 12, 2009 11:22 PM

Another flaw, the return _instance; needs to go one bracket down :) (it currently returns in the if statement)

# Brad said on Friday, July 17, 2009 6:24 AM

I keep revisiting this code, as im using it throughout my applications now. I have a question, would you want to put a volatilewrite for setting initialize?

# luisabreu said on Friday, July 17, 2009 7:53 AM

I'd say no. Check Joe Duffy's excellent post I mentioned above. I think that it might help you understand why...

# J said on Friday, July 17, 2009 10:16 AM

Duffy's blog link is broken.

# luisabreu said on Friday, July 17, 2009 10:45 AM

I think it's this: www.bluebytesoftware.com/.../PermaLink,guid,543d89ad-8d57-4a51-b7c9-a821e3992bf6.aspx

# Brad said on Thursday, August 13, 2009 4:12 AM

Sorry to bring up an old post, but they also need to be made static :)

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover