Fix for intermittent java exception during compilation (generally NPE Compi...
On 06/12/2012 01:59 AM, giuliano carlini wrote:
Just to be clear, this bug (and the patch) don't involve a double check
idiom, and compiler optimization wasn't the source of the problem
either: random variation in thread scheduling was the problem.
There are two race conditions and the patch only prevents one. In the
original code the two races are:
1) The other thread sets in.thread to null just before the first
thread (in Sizer or Compiler) tries to dereference it, causing the NPE.
The patch prevents this.
2) The other thread sets in.thread to null just after the first
thread determines it's non-null but just before it does the join. So
it's doing the join when the thread field is in fact null at that
moment. The patch does nothing to prevent this.
But the "other thread" is the MessageSiphon instance and it's just set
thread to null before falling out the bottom of its run method (i.e. the
thread is guaranteed to terminate if the process gets enough cpu
resources to let that thread execute some more). So in this case the
first thread does the join and as soon as the MessageSiphon thread
terminates control in the first thread continues past the join. If the
MessageSiphon thread terminates before the first thread is able to
invoke the join that is of course also harmless.
Putting the fix in MessageSiphon was, in my opinion, vastly superior to
the Sizer and Compiler classes mucking with fields of the MessageSiphon
Iff the semantics of the thread field being set to null were different
in certain ways it might be possible to have scenario (2) tricking the
first thread into doing a join that never terminates. In this case using
a critical section (i.e. synchronizing on the instance object) is the
right solution. Also, if instead of a synchronized method a "wait" is
used with a synchronized block, then *always* confirm that what woke up
the thread from the wait was in fact what you expected and repeat the
wait if it was not. Spurious wake ups are a fact of life with Java.
Doug Lea is for sure the world's authority on Java concurrency, and
anybody getting into this area would do well to consult a book he
coauthored called "Java Concurrency in Practice."
To be clear: 1) Andrew's improvement is indeed an improvement. 2) He was not doing a double check. My reference to it is only as an example of what compiler rewrites can do to code.
"Java Concurrency in Practice" is the book I indirectly referenced. It's an excellent source.
As further evidence that there is a race in practice, I offer the existence of the package java.util.concurrent.atomic. If the Andrew's idiom worked, these classes would not be necessary.
In any case, I don't have time to discuss this further. Apologies for bailing out on this discussion.
On Jun 12, 2012, at 9:15 AM, Avrghh wrote: