ConcurrentHashMap的使用技巧
在日常开发中,资源池是经常遇到的场景,一种简单的实现是按需创建一个资源,然后放入map中缓存起来,后续使用这个资源时直接从map中获取.
最简单可靠的实现是利用HashedMap+synchronized(或者Lock)
这种方式无疑是正确的,但锁的粒度较大,高并发时性能不佳
改进的一种典型思路是利用JUC里的并发工具ConcurrentHashMap,降低锁粒度,提高并发性
http://dmy999.com/article/34/correct-use-of-concurrenthashmap里提到了一种实践,主要代码如下
private ConcurrentMap records = new ConcurrentHashMap();private Record getOrCreate(String id) { Record rec = records.get(id); if (rec == null) { synchronized (this) { rec = records.get(id); if (rec == null) { // record does not yet exist Record newRec = new Record(id); rec = records.putIfAbsent(id, newRec); if (rec == null) { // put succeeded, use new value rec = newRec; } } } } return rec;}注意此处使用了sychronized,仍然不能使用HashedMap代替ConcurrentHashMap
因为这种写法有多线程同时访问Map的get和put方法的可能,
而HashedMap的get和put方法并发环境下也是会出错的.