面试集锦(十二)hashMap

hashmap

底层是基于数组+链表实现的,真正存放数据的是entry<k,v>的数组数组

hashmap如何解决碰撞问题

当不一样的对象发生碰撞时,HashMap经过单链表来解决,将新元素加入<链表>表头(头插法),经过next指向原有的元素。单链表在Java中的实现就是对象的引用(复合)。安全

put方法

  1. 判断当前数组是否须要初始化
  2. 若是key为空,则put一个空值进去
  3. 根据key算出hashcode
  4. 根据hashcode定位所在的桶(链表)
  5. 若是桶是链表要遍历里面的hashcode和key和传入的key是否相等,相等则覆盖,并返回原来的值
  6. 若是桶是空的,说明当前位置没有数据,则新增一个entry对象写入当前位置

get方法

  1. 根据key来算出hashcode,而后定位到具体的桶中
  2. 判断该位置是不是链表
  3. 不是链表就根据key,key的hashcode是否相等来返回值
  4. 若是是链表则须要遍历知道key及hashcode相等时候返回值
  5. 啥都没有就返回null

jdk1.8作的优化

对大链表进行了优化,超过阈值后将链表修改成红黑树后查询效率大大增长(当链表较长时转为将链表红黑树),未优化以前是o(n),优化后是o(log n)数据结构

会出现的问题

jdk没有对它进行任何的同步操做,因此会出现并发访问的问题,甚至会出现死循环致使系统不可用并发

解决办法

concurrenHashMap(guava中的cache采用的就是这个)优化

concurrentHashMap

原理:concurrenthashmap采用了分段锁技术,其中segment继承于reentrantlock。每当一个线程占用锁访问一个segment时,不会影响到其余的segment线程

jdk1.7和1.8的不一样

1.7采用了分段锁,1.8取消了分段锁,改用CAS + synchronized来保证并发安全性code

1.8以后在数据结构上作了改动,超过阈值后采用红黑树保证了查询效率,甚至取消了reentrantlock(可重入锁),改为synchronized对象

相关文章
相关标签/搜索