lundi 11 décembre 2017

Impact of multiple threads using same object in a singleton class

I'm designing a module which can support different datasources. My module gets the user's company id as inputs and I must call the appropriate class based on the company id. I'm trying to incorporate some good design and avoid conditional statements where possible.

I have a FetchDataSource singleton class with this method.

    public static Communicator getCommunicatorInstance(String dataSourceType) {

        if (communicatorMap == null || communicatorMap.isEmpty())
            populateCommunicatorMap();

        if (communicatorMap.containsKey(dataSourceType))
            return communicatorMap.get(dataSourceType);
        return null;
}

"Communicator" is an interface, and the communicator map will return the appropriate instance. This is the populateCommunicatorMap() method in the same singleton class.

    private static void populateCommunicatorMap() {

        communicatorMap = new HashMap<String, Communicator>();
        communicatorMap.put("AD", new ADCommunicator());
        communicatorMap.put("DB2", new DB2Communicator());
        communicatorMap.put("MYSQL", new MYSQLCommunicator());
}

AD, DB2 and MYSQLCommunicator will implement the Communicator inteface.

The code seems to work in my test draft. The only concern I have is the HashMap will return the same object for all communication requests to the same type. I can't seem to avoid having the same instance in the hashmap if I want to avoid the conditional statements. Otherwise instead of the hashmap, I could have just make calls like this.

Communicator comm;
if (type = "AD") comm = new ADCommunicator();
if (type = "DB2") comm = new DB2Communicator();
if (type = "MYSQL") comm = new MYSQLCommunicator();

I've avoided this by using the hashmap to return an instance based on type. But then I can't avoid the singleton problem where I get the same instance.

In a multithreaded environment, which needs to support hundreds of thousands of communication requests at a time, this could be a problem considering I'll need to syncronize a lot of code in each of the Communicator classes. Is there a way I can avoid the syncronization and make it thread safe without impacting performance?

Aucun commentaire:

Enregistrer un commentaire