How do the C # and java volatile keywords behave the same?

I know in java, if you have several threads accessing a variable that is not marked as mutable, you might get some unexpected behavior.

Example:

private boolean bExit; while(!bExit) { checkUserPosition(); updateUserPosition(); } 

If you mark the bExit variable as voilatile, this will ensure that other threads see the most recent value.

Does C # do the same?

Update

For example, in C #, if you do this:

 int counter = ...; for(...) { new Thread(delegate() { Interlocked.Decrement(ref counter); } } if(counter == 0) { // halt program } 

In the above example, in C #, do I need to mark the counter variable as mutable, or will this work as expected?

+7
source share
2 answers

If you mark the bExit variable as voilatile, this will ensure that other threads see the most recent value. Does C # behave the same?


Yes, but it all depends on how you access the shared variable. as your example, if you access variyable in a stream safe manner, for example, Interlocked.Decrement , this will not be a problem even without using voilatile.

volatile (C # link from MSDN)

The volatile keyword indicates that a field can be modified by multiple threads that are running at the same time. Fields that are declared volatile do not fall under compiler optimization, which allows access by a single thread. This ensures that most of the current value is always present in the field .

What is the "volatile" keyword used for?

0
source

You need to be a little careful here, as you have chosen two different types in your examples. My general rule is that volatile is best used with booleans and everything else, you probably need some other kind of synchronization mechanism. In C # and java, volatile boolean is very often used, for example. stop a cycle or execution of a task that has visibility from multiple threads:

 class Processor { private volatile Boolean _stopProcessing = false; public void process() { do { ... } while (!_stopProcessing); } public void cancel() { _stopProcessing = true; } } 

The above will work in C # or java, and in this example, the volatile keyword means that reading in the process method will be from the actual current value, and not from the cached value. The compiler or virtual machine may otherwise allow caching of the value, since the loop does not change _stopProcessing in the process.

So the answer is yes to your first question.

While you can use volatile in int, this only helps if you are only reading or writing a single value. As soon as you do something more complex, such as increasing, you need some other kind of synchronization, such as using locks. In your second example, however, you are still reading the counter value without any synchronization, so you effectively rely on other counter actions that need to be synchronized (for example, with a lock).

In your second example, you would still be better off marking your int as mutable, so you can again be sure that you are getting the current value, not some cached version. However, using volatility alone is not enough, because reading below can overlap with the standard decrement (counter), and not with the correct use of locking.

0
source

All Articles