ConcurrentHashMap融合了Hashtable和HashMap二者的优势。
Hashtable是做了线程同步,HashMap未考虑同步。所以HashMap在单线程下效率较高,Hashtable在多线程下同步操作能保证程序的正确性。 但是Hashtable每次执行同步操作都需要锁住整个结构。

ConcurrentHashMap的出现就是为了解决Hashtable同步lock整个数据结构的问题。ConcurrentHashMap锁的方式是细颗粒度。
ConcurrentHashMap将Hash表分为16个桶(默认值),诸如get/put/remove操作只需要锁着需要的单个桶即可。
ConcurrentHashMap只有在size等操作的时候才会锁住整个Hash表。
下面是自己实现的一个ConcurrentHashMap的本地缓存的例子:ConcurrentHashMap 和Guava cache相比,需要自己显示的删除缓存

1import java.util.concurrent.ConcurrentHashMap; 2 3public class ConcurrentHashMapTest { 4 5 private static ConcurrentHashMap<String, String> cacheMap = new ConcurrentHashMap<>(); 6 7 /** 8 * 获取缓存的对象 9 * 10 * @param account 11 * @return 12 */ 13 public static String getCache(String account) { 14 15 account = getCacheKey(account); 16 // 如果缓冲中有该账号,则返回value 17 if (cacheMap.containsKey(account)) { 18 return cacheMap.get(account); 19 } 20 // 如果缓存中没有该账号,把该帐号对象缓存到concurrentHashMap中 21 initCache(account); 22 return cacheMap.get(account); 23 } 24 25 /** 26 * 初始化缓存 27 * 28 * @param account 29 */ 30 private static void initCache(String account) { 31 // 一般是进行数据库查询,将查询的结果进行缓存 32 cacheMap.put(account, "18013093863"); 33 } 34 35 /** 36 * 拼接一个缓存key 37 * 38 * @param account 39 * @return 40 */ 41 private static String getCacheKey(String account) { 42 return Thread.currentThread().getId() + "-" + account; 43 } 44 45 /** 46 * 移除缓存信息 47 * 48 * @param account 49 */ 50 public static void removeCache(String account) { 51 cacheMap.remove(getCacheKey(account)); 52 } 53}