1、正确应用举例:
static Map<Integer,Integer> map = new ConcurrentHashMap(); // static Map<Integer,Integer> map = new HashMap(); public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newCachedThreadPool(); for (int i = 0; i < 1000000; i++) { final int j = i; service.submit(new Runnable() { @Override public void run() { map.put(j, j); } }); } Thread.sleep(1000); System.out.println(map.size()); service.shutdown(); } |
put 时候 ConcurrentHashMap 的put方法加锁了,所以插入1000000数据不会出现丢失情况;
HashMap会出现数据丢失。原因:假如2个线程同时put , 且 “key” 对应的底层数组位置相同(hash冲突),其中一个线程可能会覆盖另一个线程put的值;
2、错误应用
static Map<Object, Object> map = new ConcurrentHashMap<>(); public static void main(String[] args) throws Exception { new Thread(){ @Override public void run() {TestMap.add();}}; new Thread(){ @Override public void run() {TestMap.add();}}; } static void add(){ if(map.get("num")==null) map.put("num", "0"); for(int i=0;i<1000;i++){ int num = (int)map.get("num"); map.put("num", num+1); } |
这里并不能得到想要的结果(2000),虽然put方法加了锁,但是 这里的 add() 方法并不是原子性的