简体   繁体   中英

Volatile and more threads

I'm trying to understand the volatile keyword and its proper using. Looking at the Brian Goetz's article Java theory and practice: Fixing the Java Memory Model , I'm stuck on this example:

Map configOptions;
char[] configText;
volatile boolean initialized = false;

// In Thread A
configOptions = new HashMap();
configText = readConfigFile(fileName);
processConfigOptions(configText, configOptions);
initialized = true;

// In Thread B
while (!initialized) 
    sleep();
// use configOptions

The volatile variable above is used as a "guard" to indicate that a set of shared variables had been initialized.

I understand that since java 1.5, the volatile is strong enough to ensure that when thread B reads the volatile variable, it sees all variables that was visible to the thread A at the time the thread A writes to the volatile variable.

But what if there would be a thread C doing something like this:

// In Thread C
configOptions = new HashMap();
// put something to configOptions

My question: Is the volatile strong enough to ensure that when thread B reads the volatile variable, it sees all variables from all threads. Maybe some kind of flushing all caches? If not, then such a code with 3 threads is broken, right?

per the lang spec ( http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.4 ):

A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).

and

A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

so the volatile variable itself is safe from stale cache problems. Your questions is; "what about all other variables?" Well no, the volatile keyword only affects caching on the variable it is on: all other variables on those threads are unsynchronized.

In this answer I will try to explain what volatile variables in Java is.

So, where to start?

  1. Read and write operations with volatile variables are guaranteed to be atomic, even for 64-bit length variables. Note: i++; is not atomic because technically it is three variables.

  2. Writing some value to volatile variable happens-before this value can be read from it. You can find lots of questions on SO about what happens-before is. Important : in JVM it is implemented with memory fences, store fence on writing and load fence on reading. From practical side that means when you read some value from it, you're guaranteed to see all values written to non-volatile variables before volatile write;

  3. Values written to volatile variables are available to all CPUs and all threads at once, without any CPU caches.

Now, regarding your question.

Is the volatile strong enough to ensure that when thread B reads the volatile variable, it sees all variables from all threads?

No. It is strong enough to ensure that when thread B read some value from volatile variable, it sees (will read) values from variables written before volatile write.

Maybe some kind of flushing all caches?

Actually yes, on x86 architecture volatile write empties store order buffer, volatile read empties load order buffer. If you want more details on that, you may want to read answer for this question: Java 8 Unsafe: xxxFence() instructions

If not, then such a code with 3 threads is broken, right?

This code works as intended (I guess), because thread B does volatile read prior to reading configOptions which guarantees its visibility.

Is the volatile strong enough to ensure that when thread B reads the volatile variable, it sees all variables from all threads. Maybe some kind of flushing all caches?

All variables from the volatile-writing-thread that are written prior to the volatile store will be visible.

So there is no 'flush all caches' magic.

If not, then such a code with 3 threads is broken, right?

It could very well be broken with two threads if you do not synchronize correctly. There is a reason the initialized flag is written to. That effectively flushes all the writes that occurred on that thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM