Java HashMap 和ConcurrentHashMap 的区别

1.前言

对于HashMap,大家知道存的是键值对,对于ConcertHashMap 大家了解的是用于并发编程中。除了这些初步的印象,对他们之间的区别还需要知道些什么呢,数据结构是不是越复杂越好?在开发过程当中轻量级的容器更好,还是多功能的容器结构更好呢,这些都要开发者去评估。

2.HashMap

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
}

对于hashMap,实现了Cloneable的接口,而这是需要注意的

3.ConcurrentHashMap 

public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
    implements ConcurrentMap<K,V>, Serializable {
}

对于ConcurrentHashMap 并没有实现Cloneable接口,但是实现了ConcurrentMap接口。这是为什么呢,原因就在于你要实现复制容器的接口,就必须要去读和写容器,而这在并发编程当中是存在问题的,即如何保证并发编程三要素,原子性,可见性,有序性。这里主要考虑的是违反了并发编程的可见性,多个线程操作一个容器的时候,哪个线程先读取,哪个线程可以先修改,这些都是HashMap不支持的。

3.其他简单区别

HashMap实现的方法和ConurrentHashMap实现的方法

在ConcurrentHashMap中变量用volatile修饰。

    /**
     * The array of bins. Lazily initialized upon first insertion.
     * Size is always a power of two. Accessed directly by iterators.
     */
    transient volatile Node<K,V>[] table;

ConcurrentHashMap最重要的是segment类,继承了ReentrantLock锁

ConcurrentHashMap 采用了分段锁技术,不会像 HashTable 那样不管是 put 还是 get 操作都需要做同步处理,理论上 ConcurrentHashMap 支持 CurrencyLevel (Segment 数组数量)的线程并发。每当一个线程占用锁访问一个 Segment 时,不会影响到其他的 Segment。

    static class Segment<K,V> extends ReentrantLock implements Serializable {
        private static final long serialVersionUID = 2249069246763182397L;
        final float loadFactor;
        Segment(float lf) { this.loadFactor = lf; }
    }

有兴趣的可以阅读其他文档,对于HashMap的容器扩容,hash函数,hash冲突,ConcurrentHashMap的reentrantLock锁讲的更加详细,本篇作为记录其他开发者codeReview,质疑你使用concurrentHashMap,为什么不用更轻的hashMap,接口之后是否会有性能问题,需要引入并发,这值得每个人思考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值