Does this code solve the double checked locking issue in Java?
public class DBAccessService() {
private static DBAccessService INSTANCE;
private DBAccessService() {}
public static DBAccessService getInstance() {
if (INSTANCE != null) {
return INSTANCE;
}
return createInstance();
}
private static synchronized DBAccessService createInstance() {
if (INSTANCE != null) {
return INSTANCE;
}
DBAccessService instance = new DBAccessService();
INSTANCE = instance;
return INSTANCE;
}
}
There are 2 aspects to pay attention:
getInstance()is not synchronized, so after INSTANCE is initialized there is no cost for synchronizationcreateInstance()is synchronized
So, the question is: does this code have any issues? Is it legal and always thread-safe?
For solving this particular question Java concurrency in practice (written by the team who basically wrote the java.util.concurrent library) recommends the Lazy Initialization holder class idiom (page 348 in my copy, Listing 16.6, not 16.7)
This is always legal and Thread-safe. I’m not an expert, so I can’t say this is better than your code. However, given that it is the pattern recommended by Doug Lea and Joshua Bloch, I’d always use it over code you or I have invented, as it is so easy to make mistakes (as demonstrated by the number of wrong answers to this question).
Related to the volatile issue they say: