Things You Didn’t Know About Synchronization in Java and Scala
takipiblog.com
takipiblog.com
That was a fun one to explain in office hours.
"No no, it's not enough to just put this before that, you have to establish a Happens-Before relationship."
http://stackoverflow.com/questions/16159203/why-does-this-ja...
There are definitely some surprising outcomes from the JMM, but I'm pretty sure this isn't one of them. If I recall correctly, starting a thread automatically synchronizes the current thread with the first thing the child thread does, without any explicit synchronization. So anything done prior to that point in the parent thread will be visible in the child.
Maybe the child thread was created some time before it was started, and the initialization happened some time between those events. It was an example that a friend was working for a class, and as they often do, came to me for help on why it wasn't behaving as expected.
I looked at it and I could see the problem, "you don't have any locks shared between parent and child." We added a lock, synchronized it once in each thread, and the problem went away. That's definitely a surprising outcome for anyone who is accustomed to procedural programming.
FYI, the relevant section of the JLS is 17.4.4: "An action that starts a thread synchronizes-with the first action in the thread it starts." [1].
[1] http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html...
> The write of the default value (zero, false or null) to each variable synchronizes-with the first action in every thread. Although it may seem a little strange to write a default value to a variable before the object containing the variable is allocated, conceptually every object is created at the start of the program with its default initialized values.
I can't get that to jibe in my memory though against:
> The final action in a thread T1 synchronizes-with any action in another thread T2 that detects that T1 has terminated.
> T2 may accomplish this by calling T1.isAlive() or T1.join().
If we were looking into the threads, it would have been obvious that we should wait for the thread to finish before expecting to find a completed value in it other than the default. That's not what happened.
It's unfortunate that I didn't get a copy of the code in question, because it was a genuine idiosyncrasy in Java and by the time I got around to asking my friend for a copy, he had already rewritten his code in a different way that didn't hit the same bug.
Didn't use revision control, got his degree didn't care to repeat the same miserable exercises, now probably hacking ruby in his day job like me (except I promise I'm using revision control.)
It could be just me but I think the author should've mentioned alternative concurrent programming models available for JVM such as Akka.
At a bare minimum the changes to the location of the head/tail of a queue will need to be visible to multiple threads requiring volatile variables.
The java concurrent queues don't actually use synchronization blocks, they use native CAS operations but thinking that akka removes shared thread state entirely is dangerous.
The costs of synchronised blocks is high on the JVM. They defer to the operating system for thread scheduling, they enforce a memory barrier meaning all data is flushed out to RAM rather than CPU caches, and multithreaded code dirties CPU caches, reducing performance.
More server side code should be single threaded than not in my opinion.
That said, I completely agree. Many times making a single threaded system faster will improve performance vs making it parallel.
A little old but Oracle JRockit: The Definitive Guide is a pretty good book on the JRockit JVM.
Or is this book applicable beyond Java?