bill pugh singleton, why thread safe?
Asked Answered
J

3

16

Why is Bill Pugh's Singleton design pattern thread safe?

public class Logger {
    private Logger() {
        // private constructor
    }

    // static inner class - inner classes are not loaded until they are
    // referenced.
    private static class LoggerHolder {
        private static Logger logger = new Logger();
    }

    // global access point
    public static Logger getInstance() {
        return LoggerHolder.logger;
    }

    //Other methods
}
Josephjosepha answered 9/6, 2018 at 6:0 Comment(4)
Your answer is within comments itselfFontanel
Because the semantic for loading and initializing classes is defined in a way that it is only done once and the static final fields are published safely.Ayannaaycock
Brian Goetz explains this best. You should read his book Java Concurrency in Practice for the full explanation. For the abridged version, see this SO question: #802493 (But basically, the static keyword is special in Java, and implies a happens-before edge due to the way Java classes are loaded and initialized.)Hampstead
@AndyTurner Both final and static do. It's one or the other, it doesn't need to be final. Didn't double check but I'm sure that's in Brian Goetz's book. Please check it again!Hampstead
L
6

Lets take a look at the comments:

// static inner class - inner classes are not loaded until they are referenced.

The "loading" is the process of initialising the inner class (LoggerHolder).

"until they are referenced" means the inner class (LoggerHolder) is not initialised until the LoggerHolder.logger static field is referenced ("used somewhere") in this case.

So the call to getInstance() references LoggerHolder.logger and starts the initialisation of the LoggerHolder inner class.

The whole process of initialising a class is synchronised by the JVM.

From the relevant documentation:

Because the Java programming language is multithreaded, initialization of a class or interface requires careful synchronization

The implementation of the Java Virtual Machine is responsible for taking care of synchronization and recursive initialization

The initialisation of the static field:

private static Logger logger = new Logger();

is a part of the inner class initialisation and this whole initialisation process ("loading") is effectively synchronised by the JVM.

Lupitalupo answered 27/11, 2021 at 7:56 Comment(0)
T
-1

I think because of definition of 'static' in java, the inner class and the inner Object (logger in this case) load once with the class loader by jvm.

I think its better to define the logger object as final. Second or other threads cannot instantiate the object again!

Tevet answered 26/3, 2020 at 12:25 Comment(0)
D
-1

Here LoggerHolder is private static inner class, will be loaded for first call. As mentioned in below section the class initialization is always sequential, so if 2 threads access the class one thread has to wait until other thread has initialize the class, that's the reason it is thread safe.

https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom#Example_Java_Implementation

Devoirs answered 21/7 at 3:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.