package Other;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author vincent
* @description 面试map归纳
* @Date 2020-03-17 15:06
*/
public class LMap {
public void LHashMap(){
HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
// hashmap 从数组 - 链表 - 红黑树
// 容量超过8时,会决定是否变更结构为 红黑树
// 容量低于6时 会决定是否变更为 链表
// hashmap 初始容量是 2^4 16 初始因子是0.75f 最大容量为2^31
// hashmap put操作会计算key的hashcode然后与右移16位的结果异或 来决定index 减少碰撞
// index = hash & (len - 1)
objectObjectHashMap.put("key","value");
// 当hashmap容量达到负载因子时,会扩容*2
// 扩容的同时,会重新计算key的hash进行散列
objectObjectHashMap.get("key");
// java7 链表是头插法,在resize的时候多线程时可能会出现环链
// java8 链表是尾插法,且加入了红黑树
}
/**
* 并发安全的hashmap
* 并发安全的还有Hashtable 和 collecttions下的 synchronizeMap
*/
public void LConcurrentHashMap(){
// 并发安全的map
ConcurrentHashMap<Object, Object> objectObjectConcurrentHashMap = new ConcurrentHashMap<>();
// 通用特性,和hashmap一样 默认16容量 0.75f负载因子
// jdk1.7 1.8区别 1.7结构上多了一层segment和分段锁 1.8结构上取消了segment和分段锁改用synchronize+cas
// CAS的理解是先读 再写 再读 两次读的结果一致才提交 衍生出ABA问题,即操作数被修改了两次,一般场景化是加版本号 时间戳控制
// put操作 hash计算不变,但是1.7版本因为多了segment结构,会先根据hash定位一个segment 锁在segment上,取锁失败会自旋等待,自旋时间超时会进入wait
// 1.8版本 锁的是位置 计算位置,判断是否有值,无值cas插值,有值取锁失败自旋,成功则加锁插值
objectObjectConcurrentHashMap.put("key","val");
// get操作 没有锁的概念,随便取,但是因为value上加了volatile关键字,保证了数据的可见性 有序 原子
objectObjectConcurrentHashMap.get("key");
}
public static void main(String[] args) {
}
}
面试相关-从HashMap聊到ConcurrentHashMap
最新推荐文章于 2024-07-09 16:46:46 发布