集合之CurrentHashMap 1.7总结

文章目录

    • 底层实现
    • 构造方法默认的三个参数
    • 什么是Unsafe类?它有什么作用?
    • 为什么CurrentHashMap 调用Unsafe方法不会报错?我们自己创建的对象调用会报错?
    • CurrentHashMap的key,value可以为null吗?
    • CurrentHashMap如何计算size?
    • 总结流程图
      • PUT:
      • GET:

底层实现

  • 数组+链表+Segment分段锁

构造方法默认的三个参数

  • DEFAULT_INITIAL_CAPACITY=16; //默认的初始化容量,表示每个segment下的每个默认数组大小

  • DEFAULT_LOAD_FACTOR= 0.75f; // 负载因子

  • DEFAULT_CONCURRENCY_LEVEL=16; //并发级别,默认16,表示segment数组大小。

  • 构造方法总结:ConcurrentHashMap中保存了一个默认长度为16的Segment[]数组,每个Segment数组中保存了一个默认长度为2的HashEntry[]数组,我们添加元素,是存入对应的Segment数组中的HashEntry[]数组中。

什么是Unsafe类?它有什么作用?

  • Unsafe类是在sun.misc包下,不属于Java标准。很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty、Hadoop、Kafka等。
  • 使用Unsafe可用来直接访问系统内存资源并进行自主管理,Unsafe类在提升Java运行效率,增强Java语言底层操作能力方面起了很大的作用。
  • Unsafe提供了一些低层次操作,如直接内存访问、线程调度等。
  • 官方并不建议使用Unsafe。

为什么CurrentHashMap 调用Unsafe方法不会报错?我们自己创建的对象调用会报错?

  • 因为我们自己创建的对象使用的类加载器是ApplicationClassLoader,当调用class.getClassLoader()方法后返回不为null,所以会直接抛出异常,而CurrentHashMap使用的类加载器是BootstrapClassLoader,调用class.getClassLoader()后返回为null,所以会直接返回对象。

  • 具体源码如下:

private Unsafe() {
}
public static Unsafe getUnsafe() {
    Class var0 = Reflection.getCallerClass(2);
    if (var0.getClassLoader() != null) {
        throw new SecurityException("Unsafe");
    } else {
        return theUnsafe;
    }
}

CurrentHashMap的key,value可以为null吗?

  • 都不可以,会报错。

CurrentHashMap如何计算size?

  • 遍历每个segment,先得到总数,然后得到修改的次数,然后修改次数和上一次修改次数对比,如果有变化,则代表被修改了,则重新进行遍历,并且次数+1。如果遍历次数超过阈值,则对每一个segment上锁,然后遍历。

总结流程图

PUT:

集合之CurrentHashMap 1.7总结_第1张图片

GET:

集合之CurrentHashMap 1.7总结_第2张图片

你可能感兴趣的:(java,开发语言)