import java.util.function.Supplier;
class Ideone {
public static void main
(String[] args
) { Singleton.setSingletonFactory(SubSingleton.SUB_SINGLETON_FACTORY);
Singleton instanceOne = Singleton.getInstance();
Singleton instanceTwo = Singleton.getInstance();
System.
out.
println(instanceOne
== instanceTwo
);
try {
SubSingleton.SUB_SINGLETON_FACTORY.get();
System.
out.
println("Rightfully thrown " + e
); }
}
}
class Singleton {
private static volatile Singleton INSTANCE = null;
private static Supplier<? extends Singleton> factory;
public static void setSingletonFactory(Supplier<? extends Singleton> factory) {
Singleton.factory = factory;
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = factory.get();
}
}
}
return INSTANCE;
}
protected Singleton() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
// Set attribute of Singleton as necessary
} else {
throw cannotReinitializeSingletonIllegalStateException();
}
}
} else {
throw cannotReinitializeSingletonIllegalStateException();
}
}
}
}
class SubSingleton extends Singleton {
public static final Supplier<SubSingleton> SUB_SINGLETON_FACTORY = SubSingleton::new;
private SubSingleton() {}
}