views:

75

answers:

2

Hi Everyone,

I have a class that contains a boolean field like this one:

public class MyClass
{
    private bool boolVal;
    public bool BoolVal
    {
        get { return boolVal; }
        set { boolVal = value; }
    }
}

The field can be read and written from many threads using the property. My question is if I should fence the getter and setter with a lock statement? Or should I simply use the volatile keyword and save the locking? Or should I totally ignore multithreading since getting and setting boolean values atomic?

regards,

+2  A: 

volatile alone is not enough and serves for a different purpose, lock should be fine, but in the end it depends if anyone is going to set boolVal in MyClass iself, who knows, you may have a worker thread spinning in there. It also depends and how you are using boolVal internally. You may also need protection elsewhere. If you ask me, if you are not DEAD SURE you are going to use MyClass in more than one thread, then it's not worth even thinking about it.

P.S. you may also want to read this section

Ion Todirel
Thanks for your help
Ikaso
+9  A: 

There are several issues here.

The simple first. Yes, reading and writing a boolean variable is an atomic operation.

However, unless you take extra steps, the compiler might optimize away such reading and writing, or move the operations around, which could make your code operate differently from what you intend.

Marking the field as volatile means that the operations will not be optimized away, the directive basically says that the compiler should never assume the value in this field is the same as the previous one, even if it just read it in the previous instruction.

However, on multicore and multicpu machines, different cores and cpus might have a different value for the field in their cache, and thus you add a lock { } clause, or anything else that forces a memory barrier. This will ensure that the field value is consistent across cores. Additionally, reads and writes will not move past a memory barrier in the code, which means you have predictability in where the operations happen.

So if you suspect, or know, that this field will be written to and read from multiple threads, I would definitely add locking and volatile to the mix.

Note that I'm no expert in multithreading, I'm able to hold my own, but I usually program defensively. There might (I would assume it is highly likely) that you can implement something that doesn't use a lock (there are many lock-free constructs), but sadly I'm not experienced enough in this topic to handle those things. Thus my advice is to add both a lock clause and a volatile directive.

Lasse V. Karlsen
Great answer. Thanks.
Ikaso