Q: Is there any guarantee of the actions at 0 being visible, happening-before, concurrent access on 3, or must I declare the variables as volatile?
Yes there is a guarantee. You do not need the have the synchronized
block in the main thread because there is a happens-before relationship when the threads are started. From JLS 17.4.5: "A call to start() on a thread happens-before any actions in the started thread."
This also means that if you pass your o
into the thread constructor you wouldn't need the synchronized
block around (3) either.
Actions on (4) logically happen after (3), but there's no happens-before relation from (3) to (4), as consequence of synchronizing on a different monitor.
Yes and no. The logical order means that in the same thread there is certainly a happens-before relationship even though it is different monitor. The compiler is not able to reorder 3 past 4 even though they are dealing with different monitors. The same would be true with an access to a volatile
field.
With multiple threads, since (3) is only reading the object then there is not a race condition. However, if (3) was making modifications to the object (as opposed to just reading it), then in another thread those modifications may not be seen at (4). As you quote and @StephenC reiterates, the JLS says that the happens-before relationship is only guaranteed on the same monitor. JLS 17.4.5: "An unlock on a monitor happens-before every subsequent lock on that monitor."
The point above would remain true, even if there was synchronization on sharedMonitor after the unlock of (4).
See above.
Actions on (4) do not happen-before the access on (5), even though the main thread awaits for the other tasks to terminate
No. Once the main thread calls thread.join()
and it returns without getting interrupted then the main thread is synchronized fully with the memory of the thread it joined with. There is a happens-before relationship between the thread being joined with and the thread doing the joining. JLS 17.4.5: "All actions in a thread happen-before any other thread successfully returns from a join() on that thread."