今天无意中看到以前写的代码,是一个单例的工厂模式实现,代码片段如下:
private static Map daoMap = new HashMap();
public static Dao createDao(String className) {
Dao dao = (Dao) daoMap.get(className);
if (dao != null) {
return dao;
} else {
dao = (Dao) Class.forName(className).newInstance();
daoMap.put(className, dao);
return dao;
}
}
这段代码是在一个Java EE项目的一个工厂类里发现的,今天看来,在并发稍大点儿的时候,它就会出现问题,因为HashMap是线程不安全的。于是写了段代码测试一下HashMap在并发写入时会出什么问题。
测试类:
public class Test {
static Map<String,String> map = new HashMap();
static int N = 1000;
static CountDownLatch startSignal = new CountDownLatch(1);//闭锁
static CountDownLatch doneSignal = new CountDownLatch(N);
/**
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < N; i++) {
final int j = i;
new Thread(new Runnable(){
public void run() {
try {
startSignal.await();//使当前线程在锁存器倒计数至零之前一直等待
} catch (InterruptedException e) {
e.printStackTrace();
}
map.put(Thread.currentThread().getId()+""+j, "test");
doneSignal.countDown();
}
}).start();
}
startSignal.countDown();//递减锁存器的计数,如果计数到达零,则释放所有等待的线程
try {
doneSignal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("done,size:" + map.size());
}
}
上面的测试类里用到了一个jdk1.5里出现的类CountDownLatch,闭锁。因为我们要在所有线程结束后,来检验map的size。
测试结果:
done,size:948
可见,HashMap出了问题,1000个不重复的元素只放进去948个,如果加大N的值,程序就会陷入死循环。
解决方案是将HashMap换成ConcurrentHashMap,也是jdk1.5以后才有的类。它的并发性能要比Hashtable好。
使用N=7000,进行测试:
ConcurrentHashMap测试的最好结果是:
done,size:7000, time:1735
Hashtable的最好结果是:
done,size:7000, time:1800
如果N越大,效果会越明显。
分享到:
相关推荐
HashMap为什么是线程不安全的?如何解决HashMap的线程不安全问题?
TBB 开源库及并发 Hashmap 的使用
ibatis 用HashMap解决Ibatis未知列名和列数的查询结果的resultClass映射
高级程序员必会的HashMap的线程安全问题,适用于0~2年的
HashMap介绍和使用
C++hashmap的使用实例
hashmap实例 hashmap实例hashmap实例hashmap实例
hashmap相关的面试题
hashmap中hash函数的构造问题,提供了各种构造方法。以及比较函数的构造 挺适合入门学习的
HashMap数据结构,HashMap的构造方法,HashMap的put,HashMap的get
hashmap dfa关键字替换。 附上main测试明细结果,替换时间 ok ok ok ok 。
这就有可能导致A线程和B线程同时对一个数组扩容,A线程扩容后替换掉老数组,这时B线程使用的数组实际上是A线程扩容后的数组,就会产生线程安全问题。 死锁原因 比如,当前集合数组长度为2,已经有两个元素被放在了...
用hashmap结构将字典文件中的词条装入内存,并基于该结构进行查询
HashMap存放.doc
hashMap排序,hashmap使用还是比较频繁。这时自己写的一个实现hashmap排序的例子
Hashmap详解
HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改HashMap是非synchronized,所以HashMap很快...
1. 用HashMap模拟一个网上购物车。要求:从键盘输入5本书的名称、单价、购买数量,将这些信息存入一个HashMap,然后将该HashMap作为参数调用方法getSum(HashMap books),该方法用于计算书的总价并返回。【说明:...
Javascript实现和操作HashMap,压缩包里面有hashmap定义和操作的例子
hashmap的底层及源码解析,很适合大家的学习,不要积分。