9

I know in java, if you have multiple threads accessing a variable that isn't marked as volatile, you could get some unexpected behavior.

Example:

private boolean bExit;

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

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

Does c# behave the same way?

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, in c#, do you have to mark the counter variable as volatile or this will work as expected?

loyalflow
  • 14,275
  • 27
  • 107
  • 168
  • 1
    Each *runtime* (JVM or CLR memory models) has a different set of rules with some overlap. Consider looking up correct (and incorrect) usages of `volatile` in both languages/runtimes and comparing. – user2246674 May 01 '13 at 20:07
  • The C# volatile is really reserved for usage in low memory applications and should really only be used as a absolute last resort heres some documentation to take a look at in terms of C#: http://msdn.microsoft.com/en-us/library/x13ttww7(v=vs.71).aspx – Nomad101 May 01 '13 at 20:09
  • 2
    @Nomad101 - I'm not sure what relationship there is between low memory applications and the volatile keyword. – hatchet - done with SOverflow May 01 '13 at 20:15
  • @hatchet the volatile keyword allows more than one thread to manipulate an object at a time. The use case for this in low memory devices would be to allow for one object to control multiple threads without ever instantiating more than one of that object. According to the MSDN docs for volatile (looking up the article). – Nomad101 May 01 '13 at 20:19
  • 3
    @Nomad101 - I think 99.9% or more of the cases where people are using or thinking of using volatile are entirely issues of multithreaded access to shared data, completely independent of whether the application uses a lot or a little amount of memory. – hatchet - done with SOverflow May 01 '13 at 20:21
  • "*that would gaurantee that other threads will see the most recent value.*" => Technically, the Java Memory Model only guarantees that other threads will eventually see the updated value, although multiple updates might be merged. In practice, the most recent value is generally available almost immediately. – assylias May 01 '13 at 20:23
  • It would also be useful if many threads need to read/modify the same value quickly with abundent memory (keeping a common count for example). I could see how it would be helpful in low memory situations, but that surly isn't the only use case. – Cemafor May 01 '13 at 20:24
  • I realize there are many use-cases for it but it generates some problems if not done correctly I remember reading a MSDN article about the caveats of using volatile. I am currently trying to find it. – Nomad101 May 01 '13 at 21:25
  • @Cemafor That's what `Interlocked.Increment(ref count)` and `Decrement(...)` are for. `volatile` only guarantees that the cpu caches will be bypassed and the current live value in memory will be read/written. It doesn't prevent another thread updating the value between your read and write. If you just use volatile, you'll still have a race condition (albeit one that manifests far less frequently) – Basic May 09 '16 at 20:38

2 Answers2

1

You need to be a bit careful here as you've chosen two different types in your examples. My general rule of thumb is that volatile is best used with booleans and with everything else you probably need some other kind of sync'ing mechanism. It's very common in C# and java to use a volatile boolean to e.g. stop a loop or task executing which 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 would work in C# or java and in this example the volatile keyword means that the read in the process method will be from the actual current value and not a cached value. The compiler or VM may choose to otherwise allow the value to be cached as the loop in process doesn't change _stopProcessing itself.

So the answer is yes to your first question.

Whilst you can use volatile on an int this only helps if you're only ever reading, or writing a single value. As soon as you do anything more complex, e.g. incrementing, you need some other kind of sync'ing such as your usage of Interlocked. In your second example however you are still reading the value of counter without any sync'ing so you're effectively relying on other usages of counter to be sync'ed (e.g. with Interlocked).

In your second example you would still be better off marking your int as volatile, this way you again can be sure that you're getting the current value and not some cached version. However using volatile alone is not enough because the read at the bottom could overlap with a standard decrement (counter--) rather than your correct use of Interlocked.

Matt
  • 12,569
  • 4
  • 44
  • 42
0

If you mark the bExit variable as voilatile, that would gaurantee that other threads will see the most recent value. Does c# behave the same way?


Yes, but all depend on how you access shared variable. as your example, if you access the variyable in thread safe way like Interlocked.Decrement it will not be a issue even without using voilatile.

volatile (C# Reference from MSDN)

The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times.

What is the "volatile" keyword used for?

Community
  • 1
  • 1
Damith
  • 62,401
  • 13
  • 102
  • 153
  • So I am correct in understanding that w/o volatile, you may get unexpected results when reading a non-volatile variable that is being updated my multiple threads? – loyalflow May 01 '13 at 20:23
  • 1
    I've read that volatile doesn't actually do what a lot of people think it does. I recommend reading http://www.albahari.com/threading/part4.aspx#_The_volatile_keyword – hatchet - done with SOverflow May 01 '13 at 20:27