import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapDemo1 { private static Map<Long, Integer> widgetCacheMap = new ConcurrentHashMap<Long, Integer>(); /** * @param args */ public static void main(String[] args) { for (int i = 0; i < 10000; i++) { Thread tt = new Thread(new Rund()); tt.start(); } } static class Rund implements Runnable { public void run() { test(); } /** * 1W次,总有那么几次线程不安全 */ public void test() { synchronized ("") {// 解决方案 ConcurrentHashMapDemo1 tt = new ConcurrentHashMapDemo1(); tt.set(); int s1 = widgetCacheMap.get(1L).intValue(); tt.change(); int s2 = widgetCacheMap.get(1L).intValue(); if (s1 == s2) { System.out.println(s1 + ":" + s2); } } } } public void set() { Map<Long, Integer> mm = new HashMap<Long, Integer>(); mm.put(1L, 1); widgetCacheMap = mm; } public void change() { Map<Long, Integer> mm = new HashMap<Long, Integer>(); mm.put(1L, 2); widgetCacheMap = mm; } }
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class ConcurrentHashMapDemo2 { public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { System.out.println(test()); } } private static int test() throws InterruptedException { ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>(); ExecutorService pool = Executors.newCachedThreadPool(); for (int i = 0; i < 8; i++) { pool.execute(new MyTask(map)); } pool.shutdown(); pool.awaitTermination(1, TimeUnit.DAYS); return map.get(MyTask.KEY); } } class MyTask implements Runnable { public static Object lock = new Object(); public static final String KEY = "key"; private ConcurrentHashMap<String, Integer> map; public MyTask(ConcurrentHashMap<String, Integer> map) { this.map = map; } @Override public void run() { for (int i = 0; i < 100; i++) { synchronized (lock) { // 解决方案 this.addup(); } } } private void addup() { if (!map.containsKey(KEY)) { map.put(KEY, 1); } else { map.put(KEY, map.get(KEY) + 1); } } }
总结:ConcurrentHashMap是线程安全的,那是在他们的内部操作,其外部操作还是需要自己来保证其同步的,特别是静态的ConcurrentHashMap,其有更新和查询的过程,要保证其线程安全,需要syn一个不可变的参数才能保证其原子性