直接用ConcurrentHashMap代替HashMap引发的问题

看到大型网站系统与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。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值