On Wed, 13 Oct 1999, Peter Pilgrim wrote:
> Or perhaps alternatively the lazy singleton.
>
> public class NetworkPrinter {
>
> protected PaperStack paper
> protected static Object locker = new Object();
> private static NetworkPrinter thePrinter = null;
>
>
> private NetworkPrinter ( )
> {
> }
>
> public static NetworkPrinter getInstance()
> {
> if ( thePrinter != null ) {
> // Thread Safety - Double Guard technique
> synchronized( locker )
> if ( thePrinter != null ) {
> thePrinter = new NetworkPrinter();
> }
> }
> return (thePrinter);
(yea, this is somewhat offtopic, but...)
This is not properly synchronized, as I have been taught by someone with
more sense than I have.
The basic problem revolves around the fact that synchronization is
not just for serialization but is also for visibility. ie. without
synchronization, you are not always guaranteed that a change made by
one thread is visible in another. Sometimes this is ok.
Although the JLS guarantees that the thePrinter reference must be
fully visible if it is visible, it doesn't guarantee that instance
variables, etc. of the class that thePrinter references are also
visible. So if the creating thread is still in the synchronized
block, then the value stored in thePrinter may be copied to main
memory, but things like instance variables may not be, so when
another thread tries to use them they are bogus.
In addition, apparently another thread could have pre-read the contents
of the object referenced by thePrinter before it reads the reference
in thePrinter.
What it boils down to is you can't cheat on synchronization.
----------------------------------------------------------------------
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]