javaHashMap与currentHashMap

JDK1.7中:

HashMap:

    hashMap的实现就是通过数组加链表的形式组成的,初始时的容量为16,0.75*16 

    通过key对数组的长度进行取模计算,然后将entry挂在数组的位置上。

为什么要扩容:

    多个entry在链表的时候,需要进行遍历,可知链表的遍历总是比较慢的

扩容时机:

    当hash值发生冲突的时候,多个key相同,同时 threshold = loadFactor * 容量(大于数组的长度乘以加载因子的值(默认情况下数组长度是16*0.75=12时))且此时突然需要增加一个entry的时候。

线程不安全:

    就是出现在扩容的时候,会调用一个transfer(转移数组)的扩容方法:

    javaHashMap与currentHashMap_第1张图片

    详情见:https://www.cnblogs.com/somelog/p/9299056.html

 

currentHashMap:

  • 利用锁机制来进行同步操作,利用segment方式(即进行部分的划分)来进行,默认segment的长度为16,即一个currentHashMap最多有16个线程在进行操作,且必须是操作不同的segment才行。因此这决定了找到一个key值的时候,需要进行两次的hash定位操作,首先定位到segment,在定位到具体的key。

不同之处:

  1.     一个线程安全一个线程不安全
  2.     hashmap运行key和value为null,currenthashmap不允许
  3.     hashmap不允许在iterator遍历的情况下修改值,而currenthashmap可以

JDK1.8中:

    hashmap当链表的元素查过了8个,就会将链表转换为红黑树(看自己的博客)的数据结构。

    currentHashMap数据结构也是增加了红黑树,但是锁机制不在是采用segment的方式(但保证了segment的序列化方式),而是采用CAS(Compare-and-Swap)操作保证数据的获取以及使用synchronized关键字对相应数据段加锁实现了主要功能,这进一步提高了并发性。

   CAS:

    CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。

    CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

 

 

 

转载于:https://my.oschina.net/u/4189935/blog/3094714

你可能感兴趣的:(javaHashMap与currentHashMap)