区别: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
更多计算机编程相关知识,请访问:编程视频!!
Atas ialah kandungan terperinci hashmap和concurrenthashmap的区别是什么. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!