That get method is absolutely bonkers. Without synchronization its not guaranteed to see any of the changes produced by reportAndClear. This is because reportAndClear changes the variable (not the internals of the hashtable), but that change is not guaranteed to be seen by any thread except one that synchronizes on the same monitor that the changer synchronized on.
Also with respect to the new memory model though I have argued about this, in the old model, being that you are accessing a variable (hash) without ever synchronizing on its assignment, that reference itself could still be null. In other words, the original assignment during construction of MessageHash is only guaranteed to be seen by the thread that created the MessageHash object. And this gets into all sorts of memory model stuff so best to leave it here.
get absolutely must be synchronized.
Also I agree on the repeated calls of reportAndClear between calls to put. Its an odd situation I have never seen before. But it appears that legally put is required only to sort of iterate over each assignment to hash one at a time. Yes it can skip to the latest, but its only required to see one change per synch. Which I find quite funny. Theres a unique way to create an iterator, lol.
let me be clear on what I am saying. reportAndClear can lock hash which is ObjectA, then change hash to ObjectB. Next time lock ObjectB, then change hash to ObjectC. Then lock ObjectC, then change hash to ObjectD, etc...
(Ignoring the null issue)
Some other thread calls put and locks on ObjectA, it is only required to see the assignment made under that lock which is hash=ObjectB. Next call to put this thread lock on ObjectB. And is only required to see the assignment that took place under that lock which is hash=ObjectC. etc...
So each other thread can have its only private iteration going on due to the memory model (old or new). And each put is lost because its being made always on old objects. I agree that the threads dont have to iterate and can skip. but the most they are legally required to do is iterate one at a time.
[ June 01, 2006: Message edited by: Mr. C Lamont Gilbert ]