1

I've read about double-checked locking and its drawbacks, but I'm asking if using a synchronizedMap can be considered safe.

Here is my code:

public class EntityUtils
{
    private static final Map<String, Map<String, String>> searchMap = Collections.synchronizedMap(new HashMap<String, Map<String, String>>());

    private static Map<String, String> getSearchablePathMap(String key)
    {
        Map<String, String> pathMap = searchMap.get(key);
        if(pathMap != null) return pathMap;

        synchronized(searchMap)
        {
            // double check locking (safe for synchronizedMap?)
            pathMap = searchMap.get(key);
            if(pathMap != null) return pathMap;

            pathMap = new HashMap<>();
            pathMap.put(..., ...);
            ...
            // heavy map population operations
            ...

            pathMap = Collections.unmodifiableMap(pathMap);

            searchMap.put(key, pathMap);
        }

        return pathMap;
    }
}

Suggestions or improvements are welcome.

4

2 回答 2

4

它是安全的,但在这种情况下它没有任何优势。

双重检查锁定用于避免在最频繁的代码路径上进行昂贵的同步,但在您的情况下get()也是同步的,因此您实际上有两个同步块而不是一个。

于 2014-07-19T13:51:36.283 回答
2

java.util.concurrent.ConcurrentHashMap有一个putIfAbsent方法可能会有所帮助。

在您的场景中存在一个小障碍,如果密钥不存在,那么您的代码会创建并填充新地图。如果要在不存在的情况下设置的值具有显着的构建成本,则在“不缺席”执行路径上使用 putIfAbsent 会产生开销,但如果构建成本便宜或可以通过多次调用摊销,那么这可能很有用.

除非您在 Java 并发方面有特殊的专业知识,否则使用标准库中的方法很可能比使用自己的方法更安全。

于 2014-07-19T14:21:12.763 回答