JDoe
JDoe

Reputation: 66

Java volatile keyword

I know that there is a lot of questions about volatile but I just got confused from this discussion: Java: how volatile guarantee visibility of "data" in this piece of code?

Every web site that I read says that a variable could be stored in cached ( making this value invisible for another threads ) I even found this example https://dzone.com/articles/java-volatile-keyword-0

So my first question would be: Does Java stores variable values in cache memory ( in which one ? l1 l2 or l3 )

My other question is the visibility part. For example:

public int num1 = 1;
public int num2 = 2;
public int num3 = 3;
public int num4 = 4;
public int num5 = 5;
...
num1 = 10;
num2 = 20;
num3 = 30;
num4 = 40;
num5 = 50;

In this example the execution order of variables is not guaranteed. If I make num2 volatile it assures me that the order execution of num1, num2 and num3 will be exactly like its defined, but its not assuring me for num4 and num5 ?

EDIT I just finished reading the article of Peter Lawrey http://vanillajava.blogspot.com.es/2012/01/demonstrating-when-volatile-is-required.html and he wrote "Without volatile, this breaks down in a number of possible ways. One way is that the two threads each think they have changed the value and are waiting for the other i.e. each has its own cached copy of the value. "

Sooo I'm even more confused .. about that

Sorry for the probably dumb question but I really confused about that.

Upvotes: 2

Views: 749

Answers (3)

Peter Lawrey
Peter Lawrey

Reputation: 533880

Most programs, including the JVM do not explicitly place variables in any particular cache. The only decision the JIT makes is

  • does it eliminate the variable entirely?
  • does it place it in a register and which one?
  • does it place it on the stack in memory? (And where relative to the top of the stack)
  • does it place it in an object on the heap? (And where in the object)

The only choice you have is whether the variable is in an object or on the stack. (You also have the choice to avoid using a variable at all) note, if you place the field in an object the jit can still put it only the stack if it can avoid creating the object.

The only visibility guarantee that making num2 volatile provides is that if you see num2 == 20 you must see num1 == 10. You are also guaranteed you will see num2 == 20 at some point in other threads. You may see num3 == 3 or num3 == 30. It's possible you might never see num3 in another thread as it's not volatile or final. You might see num3 == 0 which is the uninitialised value if you read that field in another thread before num2 is written a second time.

each has its own cached copy of the value.

This is not determined by Java but is an implementation detail of CPUs. Each core has it's own L1 and L2 caches in x64, Sparc and ARM. These caches are local to each core for speed which means they might not be in sync with each other. Ensuring they are always in sync would slow them down dramatically.

Upvotes: 3

Chriss
Chriss

Reputation: 5639

The order of the assignments is not affected by volatile. The keyword volatile guarantees that multiple threads accessing e.g an int-value 'see' the same value. The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory". Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.

Upvotes: 0

Alexander Rühl
Alexander Rühl

Reputation: 6959

When you look for an exact description of such behaviour, it's always good to have a look into the Java Language Specification. In the linked chapter, you'll find information about threading behaviour and compiler reordering and how volatile comes into play here.

Upvotes: 0

Related Questions