Singleton is a widely used Design Pattern which guarantees a single instance of a given class is created within an application process. This is a very good design pattern for creating instances which have a very high cost for creation in terms of memory and cpu.
A typical Singleton class for a UserService will look like following;
public class UserService {
record User(String firstName, String lastName) {
public String toString() {
return firstName + " " + lastName;
}
}
private static UserService INSTANCE;
public static UserService getInstance() {
if (INSTANCE == null) {
INSTANCE = new UserService();
}
return INSTANCE;
}
private UserService() {
// Long running loading
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public User getCurrentUser() {
return new User("John", "Doe");
}
}
Even though this implementation looks like safe this will create multiple instances of UserService classes when used in a multi threaded environment due to race condition. To solve this issue the getInstance method can be re-written with double checking as following;
private volatile static UserService INSTANCE;
public static UserService getInstance() {
var instance = INSTANCE;
if (instance == null) {
synchronized (UserService.class) {
instance = INSTANCE;
if (instance == null) {
INSTANCE = instance = new UserService();
}
}
}
return instance;
}
Here we are making INSTANCE variable volatile so that it is guarantees visibility to all threads and two null checks one inside of a synchronized block to support atomicity between multiple threads. private final static UserService INSTANCE = new UserService();
public static UserService getInstance() {
return INSTANCE;
}
LazyConstant brings the goodness of both worlds by avoiding the complexity of double null checking and lazy initialisation even when initialisation may have blocking I/O and take longer to load.
private static LazyConstant<UserService> INSTANCE = LazyConstant.of(UserService::new);
public static UserService getInstance() {
return INSTANCE.get();
}


No comments:
Post a Comment