Noah Blumenthal's Blog

September 25, 2009

When (not) to use volatile

Filed under: Uncategorized — noahblu @ 4:07 pm

I was banging my head against a wall when I found this post by Jerome Laban about the volatile keyword.  I made the mistake of thinking that volatile would be sufficient in this situation:

   1: private volatile int _counter = 0;

   2: ...

   3: private void SomeMethodThatIsCalledByMultipleThreads()

   4: {

   5:     _counter++;

   6: }

and I was surprised when some of my unit tests were not running correctly (on a side note, I usually unit test multi-threading issues by issuing a command 100 or 1000 times.  I’m interested in hearing how you test that kind of stuff).

Turns out that if I thought about it a little more I would have realized that this won’t do what you (might) expect.  You see the volatile keyword just tells the system never to cache this variable – that’s especially important in multi-processor systems (and who doesn’t have at least 2 cores nowadays?) where each processor might have a different cache of the variable value.

So by using the volatile keyword you’re telling the processor to always get the latest version of the variable from memory.  So why is the above code not thread safe?

Well, remember that the incrementing a variable is a multi-step process:

  1. load variable into a register
  2. increment
  3. save back from the register

Now the thread might pause at any point in this process!  What happens if Thread A does step 1 and then gets paused, then Thread 2 does step 1?  After both threads run, _counter will only have incremented by 1!  So even though you’re always reading the current value, your increment isn’t thread safe.

So this is where you say “hey – I don’t really need the volatile keyword here.  I need a lock instead”.  And you’d be right:

   1: private volatile int _counter = 0;

   2: private object _myLocker = new object();

   3: ...

   4: private void SomeMethodThatIsCalledByMultipleThreads()

   5: {

   6:     lock(_myLocker)

   7:         _counter++;

   8: }

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: