参考资料:
https://stackoverflow.com/questions/35534906/java-hashmap-getobject-infinite-loop
Map的一些实现类有及其特性
类 |
线程安全 | 特性 |
Hashtable |
是 | Key不能为null |
HashMap |
否 | 读写效率最高,但在Java6多线程环境下使用不当可能陷入死循环,进而导致CPU使用率过高(原理可参见:http://coolshell.cn/articles/9606.html) |
Collections.synchronizedMap |
是 | Collections.SynchronizedMap在Map所有方法基础上加锁,效率与HashTable相当 |
ConcurrentHashMap |
是 | 采用分段锁,get一般不加锁,put分段锁,key/value不能为null,效率仅次于HashMap |
以下代码测试各类的读写效率
import java.util.Collections; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * @Description: 测试map */ public class ThreadMapTest { public static void main(String[] args) throws InterruptedException { Map<Integer, Integer> hashtable = new Hashtable<>(); Map<Integer, Integer> hashmap = new HashMap<>(); Map<Integer, Integer> synchronizedHashMap = Collections.synchronizedMap(new HashMap<>()); Map<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>(); test(hashtable); test(hashmap); test(synchronizedHashMap); test(concurrentHashMap); } private static void test(Map<Integer, Integer> map) throws InterruptedException { int testTimes = 5; long totalTimeMillis = 0; for (int k = 0; k < testTimes; k++) { totalTimeMillis += costTimeMillis(map); } System.out.println("Test " + map.getClass() + " average time " + (totalTimeMillis / testTimes)); } private static long costTimeMillis(Map<Integer, Integer> map) throws InterruptedException { int count = 5; ExecutorService executorService = Executors.newFixedThreadPool(count); long startMillis = System.currentTimeMillis(); for (int i = 0; i < count; i++) { executorService.execute(new Runnable() { @Override public void run() { for (int j = 0; j < 500000; j++) { map.put(0, 0); map.get(0); } } }); } executorService.shutdown(); executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); return System.currentTimeMillis() - startMillis; } }
输出结果如下:
Test class java.util.Hashtable average time 267 Test class java.util.HashMap average time 67 Test class java.util.Collections$SynchronizedMap average time 262 Test class java.util.concurrent.ConcurrentHashMap average time 167