Why Atomic operations are not always thread safe

A question I saw on StackOverflow:

Is accessing a bool field atomic in C#? In particular, do I need to put a lock around:

class Foo
{
private bool _bar;

//... in some function on any thread (or many threads)
_bar = true;

//... same for a read
if (_bar) { ... }
}

This question was answered quickly by several users that quoted C# spec, similar posts and the holy bible (ok maybe not the holy bible :) ).


The answer given was that reading or writing a boolean value is atomic (as well as other basic value types such as byte, int and so on).


Although the variable is atomic it does not mean that it's impossible to create a Racer condition while using it.


 


So How can I Create Racer Condition with an Atomic Operation?


Very Simple: All you have to do is use it in an if statement:

If(_bar)
{
//Do Something
}

What If _bar value is altered by another thread while we're inside the curly brackets? obviously it depends.
In case we're planing on _bar value to remain true while we're inside the condition we can be sadly mistaken.


And so the atomic value is only "thread safe" per operation not for the whole application.


It's very easy to fix this - just put a lock around the if statement:

lock(syncObject)
{
If(_bar)
{
//Do Something
}
}

Synchronized Collections


Many .NET collection have a synchronized version that can be created by calling Synchronized(...) function.


Ex. to create a new synchronized ArrayList call ArrayList.Synchronized(new ArrayList()). To create a Sync Queue call Queue.Synchronized(new Queue()) and so on.


The synchronized collection is Thread safe per operation as well meaning that you can call each method from multiple threads without worrying that a race condition might occur.


However there is a problem in the following code:

if(queue.Count > 0)
{
var item = queue..Dequeue();
// do something
}

Can you guess what it is?

Labels: