Reputation: 21
I have a web app that will access a distributed map via the Hazelcast client on each doPost() to the servlet. My question is should I use a Singleton to access the client from all the different servlets, and is this thread safe?
This is my class Singleton class:
public class HazelcastDistributedCacheClientSingleton {
//Properties from FrameworkResources.properties file.
private static String hazelcastEnvironmentName = null;
private static final String mapName = "wfc";
//COnstructor
private HazelcastDistributedCacheClientSingleton() {
}
//Get the Map
public static IMap<String, Object> getMap() {
// Make sure we have a name for the IMap
if (hazelcastEnvironmentName == null) {
hazelcastEnvironmentName = "DEV";
}
return getHazelcastClient().getMap(mapName);
}
public static Object getSessionObj(String key){
return getMap().get(key);
}
public static void setSessionObj(String key, Object value){
getMap().set(key, value);
}
public static void removeSessionObj(String key){
getMap().remove(key);
}
//The client singleton
private static HazelcastInstance hzClientInstance = null;
// Get the client singleton
public static HazelcastInstance getHazelcastClient() {
// Create a client instance if not already exists
if (hzClientInstance == null) {
// Create a synchronized block
synchronized (new Object()) {
// Double check that we did not do this in another thread
if (hzClientInstance == null) {
//Get startup parms from config file
try {
hazelcastEnvironmentName = java.util.ResourceBundle.getBundle("FrameworkResources").getString("HazelcastEnvironmentName");
} catch (MissingResourceException e) {
hazelcastEnvironmentName = "DEV";
}
// Configure Client
ClientConfig clientConfig = new ClientConfig();
// Set the group name to segregate dev, test, prod caches
clientConfig.getGroupConfig().setName(hazelcastEnvironmentName).setPassword(hazelcastEnvironmentName);
hzClientInstance = HazelcastClient.newHazelcastClient(clientConfig);
}
} //end synchronized block
}
// Return the client instance
return hzClientInstance;
}
}
Upvotes: 2
Views: 1265
Reputation: 11307
HazelcastInstances (client or server) are threadsafe and are designed to be shared between threads. It is best to make it a singleton.
A few comments:
1: make sure hzClientInstance is volatile. Otherwise you will have a broken the double checked locking implementation. Probably you also want to make hazelcastEnvironmentName volatile.
2: you can't synchronize on synchronized new Object()) since this object will not be shared between threads. I would synchronize on 'this' or create a lock object as final field in the HazelcastDistributedCacheClientSingleton
3: don't retrieve the IMap every time you need it. Put it in a (volatile) field the first time you retrieve it.
Upvotes: 1