ConcurrentHashMap的putIfAbsent总结
最近在设计一个可缓存的类,发现putIfAbsent使用还是有些坑要注意的,总结一下。之前的代码如下
private static ConcurrentHashMap<String, Pattern> compliedPattern = new ConcurrentHashMap<String, Pattern>();public static Pattern getPattern(String pattern) {return compliedPattern.putIfAbsent(pattern, Pattern.compile(pattern));}
?之前以为这样一行代码就完美了,结果测试每次都返回null,查看api看到文档:
public static Pattern getPattern(String pattern) {Pattern p = Pattern.compile(pattern);Pattern ret = compliedPattern.putIfAbsent(pattern, p);if (ret == null) {return ret;} else {return p;}}?但这样还搞个毛的缓存啊,每次都会compile了。正确的解法是:
public static Pattern getPattern(String pattern) {Pattern ret = compliedPattern.get(pattern);if (ret == null) {Pattern newPattern = Pattern.compile(pattern);ret = compliedPattern.putIfAbsent(pattern, Pattern.compile(pattern));if (ret == null) {ret = newPattern;}}return ret;}
?参考:
http://stackoverflow.com/questions/3752194/best-practice-to-use-concurrentmaps-putifabsent
http://stackoverflow.com/questions/10743622/concurrenthashmap-avoid-extra-object-creation-with-putifabsent
http://en.wikipedia.org/wiki/Double-checked_locking
?