HashMap、HashTable、ConcurrentHashMap

Java中数据存储方式最底层的两种结构,一种是数组,另一种就是链表。
数组的特点:连续空间,寻址迅速,但是在删除或者添加元素的时候需要有较大幅度的移动,所以查询速度快,增删较慢。
而链表正好相反,由于空间不连续,寻址困难,增删元素只需修改指针,所以查询慢、增删快。

1、HashMap
底层原理:
哈希表具有较快(常量级)的查询速度,及相对较快的增删速度,所以很适合在海量数据的环境中使用。
一般实现哈希表的方法采用“拉链法”,我们可以理解为“链表的数组”。每存放一个键值对,首先会调用hashcode方法来算hash值
并将其存储在hash值对应的数组里。如果对于不同的键但是有相同的哈希值,则采用链表存储的形式存储在这一个哈希值的链表里。
特点:
初始容量:16
最大容量:2的30次方:1073741824
put:允许值为null

2、HashTable
特点:
HashTable和HashMap采用相同的存储机制,二者的实现基本一致,不同的是:
2.1、HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都是synchronized。
2.2、HashTable不允许有null值的存在。
2.3、在HashTable中调用put方法时,如果key为null,直接抛出NullPointerException。其它细微的差别还有,比如初始化Entry数组的大小等等,但基本思想和HashMap一样。

3、ConcurrentHashMap
ConcurrentHashMap是线程安全的HashMap的实现。同样是线程安全的类。
synchronized关键字加锁的原理,其实是对对象加锁,不论你是在方法前加synchronized还是语句块前加,锁住的都是对象整体,
但是ConcurrentHashMap的同步机制和这个不同,它不是加synchronized关键字,而是基于lock操作的,这样的目的是保证同步的时候,锁住的不是整个对象。
事实上,ConcurrentHashMap可以满足concurrentLevel个线程并发无阻塞的操作集合对象。
从ConcurrentHashMap代码中可以看出,它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。
在ConcurrentHashMap中,就是把Map分成了N个Segment,put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中

public V put(K key, V value) {
            Segment<K,V> s;
            if (value == null)
                throw new NullPointerException();
            int hash = hash(key);
            int j = (hash >>> segmentShift) & segmentMask;
            if ((s = (Segment<K,V>)UNSAFE.getObject          // nonvolatile; recheck
                (segments, (j << SSHIFT) + SBASE)) == null) //  in ensureSegment
                s = ensureSegment(j);
            return s.put(key, hash, value, false);
        }
public V remove(Object key) {
            int hash = hash(key);
            Segment<K,V> s = segmentForHash(hash);
            return s == null ? null : s.remove(key, hash, null);
        }

通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍.
大意是:开启线程存放数据,首先算key对应的segement,如果两个线程的segement相同,则后一个进入的线程将会被阻塞,直到前一个线程完成之后才会才会被释放,
而对于不同的segement则不会影响,会正常运行。可以说concurrertHashMap是一种折中办法,在保证线程安全的情况下,又可以提高效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值