Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton with static inner class and double-checked locking

I am reading about Singleton design pattern and evaluating different implementations. I have doubt with the below implementations:

A. Singleton Implementation with static inner class

public class SingletonWithStaticClass {

private SingletonWithStaticClass(){}

private static class SingletonInnerClass{
    public static SingletonWithStaticClass INSTANCE = new SingletonWithStaticClass();

}

public static SingletonWithStaticClass getInstance(){
    return SingletonInnerClass.INSTANCE;
}

}

B. Singleton double checked locking

public class SingletonWithDoubleCheck {
private static SingletonWithDoubleCheck INSTANCE = null;

private SingletonWithDoubleCheck(){
    if(INSTANCE != null){
        throw new RuntimeException("Accessing private constructor is prohibited. Use getInstance method instead");
    }
}

public static SingletonWithDoubleCheck getInstance(){
    if(INSTANCE == null){
        synchronized (SingletonWithDoubleCheck.class) {
            if(INSTANCE == null){
                INSTANCE = new SingletonWithDoubleCheck();
            }
        }
    }
    return INSTANCE;
}

}

Which one is better?

I feel we can access the private constructor with Reflection in first implementation where as second implementation is safe (From Reflection attack).

However, I am not going to use any of these in my production code, I will use enum instead. But out of these two, isn't the first implementation is broken when considered Reflection attack?

Please correct me if my understanding is wrong.

like image 888
Somnath Musib Avatar asked Mar 14 '23 18:03

Somnath Musib


2 Answers

Both are overly complicated. The first was the best option before Java 5.0, however the second was never a good option. It didn't work before Java 5.0, it requires a volatile field and after this version you could use enum

I prefer using an enum to define a class with exactly one instance. It is a final class, thread safe, lazy loaded, and has a private constructor.

enum Singleon {
    INSTANCE;
}

The double locking singleton is only useful if you must provide configuration information in it's construction. In this case, I prefer to use Dependency Injection to provide/configure singletons and only have stateless Singletons which don't require configuration.

like image 54
Peter Lawrey Avatar answered Mar 18 '23 04:03

Peter Lawrey


Neither are good - and attempting to compare them using different scales is counter-productive.

The first is unnecessarily complex and, as you say, is open to reflection hacking, but so is the other one, just slightly less so.

The second uses a synchronized which comes with a cost.

like image 23
OldCurmudgeon Avatar answered Mar 18 '23 05:03

OldCurmudgeon