Hi,
The definitive answer to all your questions is here ...
http://en.wikipedia.org/wiki/Java_Memory_Model
http://www.cs.umd.edu/~pugh/java/memoryModel/
I'll try to help with something simpler ..
Disclaimer: in answering your questions have I have to make some gross simplifications for readability i.e. if you want a definitive answer use the document above but its a tough read.
Thread flushes are more commonly called memory
fence (usually CPU level except
java .. lol) or memory barrier (OS, language level). All answers apply Java >= 5 only (ish ;-) ).
http://en.wikipedia.org/wiki/Memory_barrier
i) Quick answer not guaranteed (thread start/completion), though note I suspect your code is synchronized (System) see below for details.
Long answer ..
- Synchronized blocks and volatiles strictly don't have to cause memory / fence barriers but its possibly best to assume they do if your struggling with the topic,
- They do guarantee "happens before ordering" which encompasses more eg Memory barriers (thread flushes) aren't the only issue you also need to prevent certain compiler/hotspot optimisations which have similar effects e.g.
shuffling your bye code (reordering).
- You can't guarantee a memory barrier / fence in java (Doug Lea has added a java fence api for Java 7).
- If the JVM decides a memory barrier is unecessary (optimisation for speed) it doesn't have to use one i.e. write to volatile variable guarantees happens before ordering not memory barrier i.e. a volatile int could be an int ;-)
Write to volatile doesn't guarantee write to main memory (strictly).
http://www.ibm.com/developerworks/java/library/j-jtp10185/index.html
Optimisation (as opposed to thread flush) problem example ...
What your code looks like (globalVar is a global non volatile boolean) ...
the equivalent java your actually running ...
If globalVar is volatile this optimisation would not be allowed (good).
ii) To work out what your code guarantees you need to need to identify sequence points, the obvious first one is thread start a new thread (thread pools make this topic harder) can see all (volatile) writes prior to its creation.
It then looks like you have none .... BUT .. what about the implementation of System.out.println ?? if you look a the Java source it looks like you have a common PrintStream and writes are synchronized soooo ... your two threads are
synchronized soo you have happens (writes flushed, read not cached, byte code can't be shuffled) before ordering (note the println could be preventing bugs ... eek)
iii) If two threads sync on THE SAME OBJECT any writes by either of the syncing threads (only) that happen before the synchronization are guaranteed to be visible to the other thread. If you have a third thread altering the same variables with no sync things get very complicated ;-)
your basically hinting as to what happens when you mix in non volatile writes from a third thread and the answer is if you try it I'd guess all most all the time you would see the results BUT categorically you can not rely on this behaviour.
Two threads syncing would not force a third CPU to uncachce using your terminology, it could do but it doesn't have to its basically what ever works best for Java it can do. Strictly any non volatile writes by the third thread thread are not guaranteed to happen before any read (volatile or not) of the first two.
Imagine three computers share the same cloud memory and have three threads one per PC (This actually exists see
http://www.terracotta.org/ and this obeys the JMM) so in effect you have three copies of the same variable (they'll actually be lots more CPU caches etc) , now when your thread sync an IP conversation is initiated that will resolve any
difference between the first two but the third can hide all its writes (non volatile) to the same variable and also ignore any writes of the other two (non volatile read).