
区别:HashMap是线程不安全的,当出现多线程 *** 作时,会出现安全隐患;而ConcurrentHashMap是线程安全的。HashMap不支持并发 *** 作,没有同步方法;ConcurrentHashMap支持并发 *** 作。
本教程 *** 作环境:windows7系统、java10版,DELL G3电脑。
hashmap和concurrenthashmap的区别
HashMap是线程不安全的,当出现多线程 *** 作时,会出现安全隐患;而ConcurrentHashMap是线程安全的。
HashMap不支持并发 *** 作,没有同步方法,ConcurrentHashMap支持并发 *** 作,通过继承 ReentrantLock(JDK1.7重入锁)/CAS和synchronized(JDK1.8内置锁)来进行加锁(分段锁),每次需要加锁的 *** 作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全。
ConcurrentHashMap采用锁分段技术,将整个Hash桶进行了分段segment,也就是将这个大的数组分成了几个小的片段segment,而且每个小的片段segment上面都有锁存在,那么在插入元素的时候就需要先找到应该插入到哪一个片段segment,然后再在这个片段上面进行插入,而且这里还需要获取segment锁。
ConcurrentHashMap让锁的粒度更精细一些,并发性能更好。
(推荐教程:java入门教程)
HashMap
HashMap是线程不安全的,在原码中对put方法没有做锁的处理,当放生多线程时,会有线程安全问题,下面通过一个简单的例子进行演示,创建三个线程,并且启动,在run方法里通过for循环给map存100个值,然后输出map的大小按正常来说,该map的大小应该是100,而这里输出了176。
class Demo implements Runnable{
static Map<String,String> map = new HashMap<>();
@Override
public void run() {
for (int i = 0; i < 100; i ++) {
map.put(i + "","value");
}
}
public static void main(String[] args) {
new Thread(new Demo()).start();
new Thread(new Demo()).start();
new Thread(new Demo()).start();
// 获取当前线程
Thread currentThread = Thread.currentThread();
// 当前线程睡眠2秒,让上面的三个线程先执行
try {
currentThread.sleep(2000);
} catch (Exception e) {
e.getMessage();
}
// 上面的线程执行完毕后输出map的大小
System.out.println(map.size());
}
}HashTable
HashTable用到了锁,而且是直接给put方法加的锁,线程肯定是安全的了,这里我们在测试线程安全的同时,看一下执行时间,这里通过put10000个数据进行测试,通过结果可以看到,map的大小确实是10000,而时间用了16ms左右。
class Demo implements Runnable{
static Map<String,String> map = new Hashtable<>();
@Override
public void run() {
long startTime = System.currentTimeMillis(); //获取开始时间
for (int i = 0; i < 10000; i ++) {
map.put(i + "","value");
}
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println((endTime - startTime) + "ms");
}
public static void main(String[] args) {
new Thread(new Demo()).start();
new Thread(new Demo()).start();
new Thread(new Demo()).start();
// 获取当前线程
Thread currentThread = Thread.currentThread();
// 当前线程睡眠2秒,让上面的三个线程先执行
try {
currentThread.sleep(2000);
} catch (Exception e) {
e.getMessage();
}
// 上面的线程执行完毕后输出map的大小
System.out.println(map.size());
}
}ConcurrentHashMap
ConcurrentHashMap用的是分段锁,哪块不安全就锁哪块,不能不锁,不能全锁,那我就块锁!看看这个块锁相对于方法锁是快了,还是慢了。
class Demo implements Runnable{
static Map<String,String> map = new ConcurrentHashMap<>();
@Override
public void run() {
long startTime = System.currentTimeMillis(); //获取开始时间
for (int i = 0; i < 10000; i ++) {
map.put(i + "","value");
}
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println((endTime - startTime) + "ms");
}
public static void main(String[] args) {
new Thread(new Demo()).start();
new Thread(new Demo()).start();
new Thread(new Demo()).start();
// 获取当前线程
Thread currentThread = Thread.currentThread();
// 当前线程睡眠2秒,让上面的三个线程先执行
try {
currentThread.sleep(2000);
} catch (Exception e) {
e.getMessage();
}
// 上面的线程执行完毕后输出map的大小
System.out.println(map.size());
}
}从结果中看到,从之前的20ms和22ms提高到了现在的17ms和18ms
更多计算机编程相关知识,请访问:编程视频!!
以上就是hashmap和concurrenthashmap的区别是什么的详细内容,
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)