I am wondering which one is better in practice in a multithreaded environment. I understand Singleton as Enum type creates an instance when the class is loaded. Other than that I don't see anything else significant. Is there any pros and cons ?
Singleton as Enum
type:
public enum Singleton {
INSTANCE;
public void doSomething(){ ... }
}
Singleton with double-checked locking
:
public class Singleton{
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
Often in multi-threaded applications, simpler, easier to understand code is more likley to work.
To my mind the first example is significantly simpler than the second and that is what matters.
The main pro of using an enum
is its much simpler and the more complicated example is not justified. The double locking example allows you to change the singleton in interesting way for unit tests, but I believe what this gives you can be solved another way.
There are more problems with Singletons, than just a correct implementation.
People often use Singletons, so they don't have to pass Objects around, where they should or they would have to pass Objects across multiple Methods.
There are quite a few examples for instantiating a jdbc connection with a Singleton.
In the methods where you need this connection, you can easily access it, because its a Singleton.
public enum DBConnection {
INSTANCE;
private Connection connection;
public Connection getConnection(){
if(connection == null){
instantiateConnection();
}
return connection;
}
}
and accessing it by
DBConnection.INSTANCE.getConnection();
But often it's better to do it with Dependency Injection and a pleasent framework. GUICE for example.
In your code you would not make a call on DBConnection.INSTANCE and than on getConnection(), you're Class would have a field DBConnection annotated with @Inject. And you just use it.
@Inject
private DBConnection dBConnection;
And the Class would be just annotated with @Singleton to be a Singleton, and the framework would assure it's a singleton.
And if you have different environments like, test and production you could let the framework inject different Objects for each environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With