Mike Kramer
Mike Kramer

Reputation: 21

Hazelcast client singleton

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

Answers (1)

pveentjer
pveentjer

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

Related Questions