• Post Reply Bookmark Topic Watch Topic
  • New Topic

Thread and volatile  RSS feed

 
Kee Kee moon
Ranch Hand
Posts: 147
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

What exactly "volatile" does in this program.


 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
volatile is telling the JVM that it should not cache the value of your instance variable between various threads but always refer to the direct value. this is to prevent problems when one thread updates a value and another thread uses a cached (but stale) value of the same variable.
 
Lucas Smith
Ranch Hand
Posts: 808
1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Could you give an example in which putting volatile changes a program's output?
Please, it's very interesting for me.
 
Sebastian Janisch
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's hard to do because the jvm works arbitrarily when it comes to threads. this is what makes it so hard to debug. Sometimes faulty programs might work, sometimes they fail.
 
Lucas Smith
Ranch Hand
Posts: 808
1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I see, but can you give an example where JVM might cache a variable for a thread?
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Trying to work out why code without "happens before ordering" fails is bad form, as there are many possibilities and they go all the way to the memory model on the CPU. What you are try to establish is happens before ordering the visibility of one threads actions to another, the problem with understanding why something fails is there is a tendency to start playing tricks e.g. synchronize on local object to get a memory barrier/fence which although they can fix a given seen issue are victim to other gotchas.

Your best googling for and reading JSR 133.

The most infamous caching example looks similar to the one listed below and I have seen something similar fail in the real world (it should be obvious there is no happens before ordering and I would leave it at that though I have seen written the cause in this case was JVM caching). Note adding volatile may not change the output but without it the result is not guaranteed / predictable.

If you look up Intel / Sparc / AMD architecture docs you'll find some really simple examples of the need for memory fences at an assembler level (memory model dependent).


// Stupid example (simplified from the initial one in this mail thread) but if one thread executes run, another thread executing run may not see stop as true.
// There is no "happens before ordering" the JVM is allowed to (doesn't have to) cache the value of stop read in run, it actually makes sense to for
// performance reasons

class wibble
{
// note not volatile and no synchronisation
private boolean stop = false;

// called from thread B after thread A calls run
public void stop {
stop = true;
}

// called by thread A
public void run () {
// Hey JVM why reread the value you already have it (faster) and its not marked volatile so the coder doesn't care :-( why should the JVM
while (!stop) {
// do something
}
}

}
 
Lucas Smith
Ranch Hand
Posts: 808
1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks!
Please consider this piece of code:



Potentially this code can run in a non-deterministic way. Am I right?
But it works well - when it comes to threads, very little is guaranteed.
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The write thread.testValue = false has no "happens before" ordering with the read of thread.testValue , ie the write is not guaranteed to have occurred in the other thread (visibility) before ANY read in the other thread as the code stands.

I like to think of each thread running in its own plain of reality weekly linked.

If your really interested in this subject have a look at something called terracota which is Java / memory model compliant you can run that program as written (with a bit of XML config) such that it will/can run each thread on a seperate JVM / physical machine now obviously each has a different physical memory but it uses "happens before ordering" as it has to to be JSR133 complient to allow threads to communicate.

So in your example your code (assuming threads on different machines) will ALWAYS fail BUT changing the variable to volatile ... the volatile write thraed.testValue = false will (if required) push the boolean value change between machines over the network and your code now always works ;-) which is why I keep think about its use purely for testing purposes as a lot of the unit test code I have seen that supposedly tests multithreaded code looks flawed to me personally.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!