The question seems to be partly answered by this answer:
Java multi-threading & Safe Publication
at least regarding "safe publication".
Now if the caller discards its reference the variable will be safe, because there exist no reference to the variable except in the final local variable.
And regarding the code examples - in my eyes both code snippets are equivalent. Introducing an additional local variable doesn't change the semantics, in both cases the compiler recognizes the reference as immutable and let you go with it.
EDIT - I am leaving this part to document my misinterpretation of the OP's question
To clarify - I take usage of final
or volatile
as granted in this example, so the proper memory barrier catering for the visibility of the object reference is there, the only point is the possible mutability of the non thread-safe object which cannot be guaranteed using memory barriers and actually has nothing to do with them. It can be taken care of either through proper synchronization or leaving only one reference to the content.
EDIT2 – after reading the OP’s comments
I have just looked at the JSR 133 FAQ - AFAIU a safe publication of a reference to object using a memory barrier doesn't guarantee that the unsychronized fields of the mentioned referenced object are visible too. Neither by final
nor volatile
.
If I am not misinterpreting this FAQ only synchronizing on the same monitor defines a “happens-before” relationship for all the writes one thread did before releasing the synchronizing lock and acquiring the lock on the same monitor by another thread.
I may be mistaken but it sounds to me as if also non-synchronized fields of the referenced object would be visible.
If using final
keyword (like in your example where the parameter gets inserted as a final
field) - only instance fields of the referenced object that themselves are final
are guaranteed to be visible after the construction of the object ends.
But in the BlockingQueue
(and as its implementation the LinkedBlockingQueue
) I see no synchronized
keyword whatsoever – it seems that it uses some very clever code to implement synchronization by using volatile
fields, to me it doesn’t sound like a synchronization on a monitor in the sense described in JSR 133.
Which would mean that common blocking queues used by Executor do not guarantee visibility of non-final fields of your Unsafe
instances. While the reference itself can be safely published using just the final
keyword, the safe publishing of the fields this reference points to requires either the fields to be final
, too, or a synchronization with a monitor shared by the writer and reader.
Don’t shoot the messenger :-).
class Executor { void execute(Runnable r) { } }
- no queue here. But the point is probably valid nevertheless... – HobokenUnsafe
is a class which has a singleton, though you can create more of them... – Solidussun.misc.Unsafe
. Edited for clarity. – Evanthe