您的位置 首页 java

hashmap和concurrenthashmap的区别是什么

区别: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());    }}

1.png

HashTable

HashTable用到了锁,而且是直接给put方法加的锁,线程肯定是安全的了,这里我们在测试线程安全的同时,看一下执行时间,这里通过put10000个数据进行测试,通过结果可以看到,map的大小确实是10000,而时间用了16ms左右。

2.png

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());    }}

3.png

ConcurrentHashMap

ConcurrentHashMap用的是分段锁,哪块不安全就锁哪块,不能不锁,不能全锁,那我就块锁!看看这个块锁相对于方法锁是快了,还是慢了。

4.png

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());    }}

5.png

从结果中看到,从之前的20ms和22ms提高到了现在的17ms和18ms

文章来源:智云一二三科技

文章标题:hashmap和concurrenthashmap的区别是什么

文章地址:https://www.zhihuclub.com/14085.shtml

关于作者: 智云科技

热门文章

网站地图