0

Is the following code thread safe?

private static HashMap<String, String> cache = null;

public static String getInfo(String key) {
    populateCache();

    return cache.containsKey(key) ? cache.get(key) : null;
}

private static void populateCache() {
    if (cache == null) {
        cache.put("hello", "world");

        // ... more population logic here
    }
}

If not, what can I do to make it thread safe?

EDIT: Thanks for the answers, I'll try out ConcurrentHashMap. However, I missed out something.. I am actually passing an object of a separate Foo class to getInfo() here:

public static Bar getInfo(Foo object) {
    object.someProperty = concurrentHashMapCache.get('something');

    return Bar.createFromFoo(object);
}

As long as different threads pass a different Foo object to getInfo, the above code should work, right?

8
  • Have you got a delete method as well? question is no because if multiple threads call the same method you can get race conditions. You can use the keyword synchronize to make it mutually exclusive Commented Nov 8, 2013 at 23:02
  • That code is not thread safe, and will fail with NullPointerException Commented Nov 8, 2013 at 23:02
  • @Vash the code is not thread safe, two threads can execute them at the same time and the cache would be populated twice. Commented Nov 8, 2013 at 23:02
  • Do not reinvent the wheel, use an already built cache like ehcache or infinispan. Commented Nov 8, 2013 at 23:03
  • @LuiggiMendoza, That was more about the thing that one thread will call an raise an exception but no joke here ;-). Commented Nov 8, 2013 at 23:04

3 Answers 3

3

HashMaps in Java are not thread safe. If you want a thread safe version use ConcurrentHashMap: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html

Sign up to request clarification or add additional context in comments.

8 Comments

or you can use HashTables which are synchronized docs.oracle.com/javase/7/docs/api/java/util/Hashtable.html
@LuiggiMendoza Yeah ConcurrentHashMaps are more efficient but I just added the possible choices for what OP wants.
@Prateek it's like offering Vector class as an option for a synchronized List: stackoverflow.com/q/1386275/1065197
@LuiggiMendoza Yes, but unless the OP is writing some production code (which I think he is not) it doesn't matter. It is not bad to know all your options both efficient and non-efficient and use one based on your needs. As mentioned in my earlier comment I was adding to the list of options that OP has.
@Prateek OP's trying to build its own cache, so looks like production code to me. If that's the main problem, then it would be better using an already tested and proven cache solutions instead of writing one from scratch. And IMO you should know they were options in the past but must not use them in current applications (at least that you're stuck with Java 1.4.2 or prior and don't have any other option =\).
|
2

It's not. Either use ConcurrentHashMap or make the public method synchronized (which makes more sense since you've got a race condition also on creating the HashMap).

2 Comments

Just to add more info to your answer.
@LuiggiMendoza : Okay, thanks. I always ask myslef "Nah, what have I messed up this time?" when I see a comment like this :).
0

Much depends not only on simply how a class is written, but also on how it will be used.

You have a single shared mutable field which makes up the state of your class's objects.

cache is populated without any attempts to synchronize access, so it is possible in a concurrent environment for two client threads to be modifying cache at the same time.

In the absence of any kind of internal syncronization, this class looks unsafe.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.