直接用ConcurrentHashMap代替HashMap引发的问题
来源:互联网 发布:淘宝身份认证失败 编辑:程序博客网 时间:2024/06/05 01:16
看到大型网站系统与Java中间件实践里边有提到直接将HashMap替换成ConcurrentHashMap时会有问题,所以我写了一段代码测试一下,测试一个数组中字符串出现的次数,结果真的有问题额。
package com.yy.ent.platform.ecommerce.common;import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; public class ConHashMapTest { private static ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<String,Integer>(); private static String[] array = {"yy","yy","welcome","java","234","java","1234","yy","welcome","java","234"}; public static void main(String[] args) { System.out.println("array size:"+array.length); for (String str : array) { new Thread(new MyTask(str)).start(); } for(Entry<String,Integer> entry : map.entrySet()){ System.out.println(entry.getKey()+":"+entry.getValue()); } } static class MyTask implements Runnable{ String key; public MyTask(String key) { this.key = key; } @Override public void run() { map.putIfAbsent(key, value) Integer value = map.get(key); if(null == value){ map.put(key, 1); }else{ map.put(key, value + 1); } } } }
运行结果:
很明显结果不正确。因为我们对map的值修改要依赖上一次的值,在多线程的环境下就会出问题,如果对于key相同就会发生漏统计,但是我还是比较疑惑测试出来的结果,key为什么会少呢,下面我对map加锁然后程序产生正确结果。
package com.yy.ent.platform.ecommerce.common;import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; public class OptimizedConHashMapTest {private static ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<String,Integer>(); private static String[] array = {"yy","yy","welcome","java","234","java","1234","yy","welcome","java","234"}; public static void main(String[] args) { System.out.println("array size:"+array.length); for (String str : array) { new Thread(new MyTask(str)).start(); } for(Entry<String,Integer> entry : map.entrySet()){ System.out.println(entry.getKey()+":"+entry.getValue()); } } static class MyTask implements Runnable{ String key; public MyTask(String key) { this.key = key; } @Override public void run() { synchronized(map){Integer value = map.get(key); if(null == value){ map.put(key, 1); }else{ map.put(key, value + 1); } }} } }
运行结果:
结果正确。如果对于值的修改要依赖上一次的值,还是直接给HashMap加锁实现好了;如果修改的值不依赖上一次的值就用ConcurrentHashMap。
1 0
- 直接用ConcurrentHashMap代替HashMap引发的问题
- HashMap与ConcurrentHashMap的区别以及hashMap的问题
- HashMap&ConcurrentHashMap的比较
- hashmap和ConcurrentHashMap相关问题
- 用SparseArray代替HashMap
- 用SparseArray代替HashMap
- HashMap与ConcurrentHashMap的测试报告
- ConcurrentHashMap:一个更好的HashMap
- ConcurrentHashMap:一个更好的HashMap
- java的HashMap与ConcurrentHashMap
- ConcurrentHashMap(并发hashmap)的使用
- ConcurrentHashMap和HashMap的区别
- ConcurrentHashMap 线程安全的 HashMap
- HashMap与ConcurrentHashMap的区别
- ConcurrentHashMap的原理和HashMap
- HashMap与ConcurrentHashMap的区别
- HashMap与ConcurrentHashMap的区别
- HashMap与ConcurrentHashMap的区别
- Ubuntu tomcat8 启动脚本(最简化)
- Linux下Oracle11G64位安装流程
- Canada Cup 2016
- 1. Two Sum&15. 3Sum
- pycharm破解
- 直接用ConcurrentHashMap代替HashMap引发的问题
- 118. Pascal's Triangle
- 283. Move Zeroes
- getApplicationContext()和Activity.this区别
- Leetcode 406. Queue Reconstruction by Height
- 27. Remove Element
- 219. Contains Duplicate II
- Listview和scrollview嵌套冲突问题
- 189. Rotate Array