Does Java volatile variables impose a happens-before relationship before it is read?

concurrency, java, multithreading

Solution

See http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility:

A write to a volatile field happens-before every subsequent read of that same field. Writes and reads of volatile fields have similar memory consistency effects as entering and exiting monitors, but do not entail mutual exclusion locking.

So the answer is yes. The write of the volatile in the constructor happens before the read of the volatile in `numCreated()`. And since the non-atomic incrementation is still done in a synchronized block, the synchronization is alright (the incrementation is not atomic, but the write of the volatile long is).

Problem

I have a piece of code which looks like this: Snippet A: ``` class Creature { private static long numCreated; public Creature() { synchronized (Creature.class) { numCreated++; } } public static long numCreated() { return numCreated; } } ``` From my understanding, since reading of `numCreated` is not synchronized, if Thread-A creates a `Creature` at 1pm, and Thread-B reads `numCreated()` at 2pm, `numCreated()` may well have returned either 0 or 1 (even when Thread-A has finished initializing the object at 1.05pm). So I added `synchronized` to `numCreated()`: Snippet B: ``` class Creature { private static long numCreated; public Creature() { synchronized (Creature.class) { numCreated++; } } public static synchronized long numCreated() { // add "synchronized" return numCreated; } } ``` and all's well, except that I was thinking, if I modify it to Snippet C, is the variable `numCreated` still synchronized properly? Snippet C: ``` class Creature { private static volatile long numCreated; // add "volatile" public Creature() { synchronized (Creature.class) { numCreated++; } } public static long numCreated() { // remove "synchronized" return numCreated; } } ``` With Snippet C, is it guaranteed that as soon as Thread-A completes object creation at 1:05pm, Thread-B's call to `numCreated()` is sure to return `1` ? PS: I understand that in a real situation I would probably use an `AtomicLong` but this is for learning purposes

Original source