I have been pointing out Sun's error in exposing its monitors. Specifically I have cited join() as a prime culprit. join() uses the 'this' object's monitor. There is another thing that occured to me today as I was writing some code. join creates a mutual synchronization boundary.
Follow these few steps;
1. Thread A sets x to a value. 2. Thread B calls thread A.join(). 3. Thread B reads the value of x.
According to documentation the JVM is free to not show thread B thread A's update of x. This is because they have not crossed any synchronization boundaries. But underneath, join() synchronizes on the thread A object (since it uses wait). So thread B will automatically flush all of its thread values and read in all new thread values. And if its thread A that sends the notify to thread B, then thread A must grab the thread A object's monitor. This means thread A will also flush its values before it dies due to this synchronization boundary.
Without that, a join would be no guarantee that you see the dying threads updated values. And even now I think the specification does not state this. But the implementaiton gives us this. Its interesting that one designs a specification and software such that you can change a great many things so long as you meet the spec. In this case though it seems like even more reason why if they tried to change join but still meet the spec they risk altering existing code in a tremendous way beyond what I thought before...