Interlocked.Exchange, thread-safety, and booleans

N

n_o_s_p_a__m

Hi, just a quick question:

I have 2 objects running in their own threads (let's call them a & b).

They both hold a reference to a common object running in a third
thread (call it c) which has a public boolean field called bCool.

So:

// a & b
class One {
private Two _myTwo = null;
public One(Two t) {
_myTwo = t;
}

public void ChangebCool(bool newVal) {
_myTwo.bCool = newVal; // safe?
}
}

// c
class Two {
public volatile bool bCool = false;
}

Both a and b can thus read and update bCool.

Is there any risk of a and b colliding on these operations?

Are boolean's thread-safe?

Is volatile even needed?

Should a & b use Interlocked.Exchange() update bCool?

Or what.

Thanks.
 
B

Bruno Jouhier [MVP]

I try to avoid "volatile" and use "lock" instead to synchronize. Of course
there is some overhead but you are on the safe side.

This being said, the assignemnt of boolean is atomic so there is no real
need for anything, not even "volatile" in your sample code.

But, things are different if you start to read the value of _myTwo.bCool
(and my guess is that you probably read it somewhere). Volatile will prevent
the compiler from optimizing the value in a register and will force a reload
from main memory every time. This is especially useful if you write a loop
like:

while (_myTwo.bCool && cond1) { /* simple code that does not reassign
_myTwo.bCool */ }

Without the volatile keyword, the compiler may be able to optimize it as:
if (_myTwo.bCool) { while (cond1) { /* simple code */ } } // may loop
forever!

So, I would keep "volatile", to be sure that you always read the current
value.

Bruno.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top