HikariCP源码之FastList

FastList源码

FastListHikariCP 中设计的本地资源列表获取资源,下面是源码的分析

属性

public final class FastList<T> implements List<T>, RandomAccess, Serializable
{
   private static final long serialVersionUID = -4598088075242913858L;
	//存储的元素类型
   private final Class<?> clazz;
   //存储的数组
   private T[] elementData;
   //元素的个数
   private int size;
   }

构造函数

构造函数没有什么过于复杂的判断,接受数组的容量,元素的类型

public FastList(Class<?> clazz, int capacity)
  {
     this.elementData = (T[]) Array.newInstance(clazz, capacity);
     this.clazz = clazz;
  }

add

add方法添加元素跟ArrayList的区别就比较大了

  • ArrayList的方法层级比较多,出入栈更频繁
  • ArrayList使用无参构造时使用了默认空数组,需要在首次添加时多了一些判断逻辑,对于Hikari来说这些判断都是无用的
  • FastList少了modCount(记录结构性修改次数的计数器)快速失败机制是一种迭代器(Iterator)在遍历集合过程中发现集合的结构性发生变化时,立即抛出 ConcurrentModificationException 异常
  • ArrayList在扩容时的计算逻辑相对复杂,考虑很多边界条件,而FastList只是简单的扩容为原来的2倍 拷贝数组时使用了 Arrays.copyOf 底层也是 System.arraycopy,但是其调用层级就变深了
/**
    * FastList和ArrayList的区别:
    * 1. ArrayList的方法层级比较多,出入栈更频繁
    * 2. ArrayList使用无参构造时使用了默认空数组,需要在首次添加时多了一些判断逻辑,对于Hikari来说
    *   这些判断都是无用的
    * 3. FastList少了modCount(记录结构性修改次数的计数器)快速失败机制是一种迭代器(Iterator)在遍历集合过程中发现集合的结构性发生变化时,立即抛出 ConcurrentModificationException 异常
    * 4. ArrayList在扩容时的计算逻辑相对复杂,考虑很多边界条件,而FastList只是简单的扩容为原来的2倍
    *   拷贝数组时使用了 Arrays.copyOf 底层也是 System.arraycopy,但是其调用层级就变深了
    */
   @Override
public boolean add(T element)
   {
      //判断有没有超过数组长度
      if (size < elementData.length) {
         elementData[size++] = element;
      }
      else {
         // 获取到当前数组的容量
         final int oldCapacity = elementData.length;
         //新增容量为原来的50%
         final int newCapacity = oldCapacity << 1;
         @SuppressWarnings("unchecked")
         //创建新的数组
         final T[] newElementData = (T[]) Array.newInstance(clazz, newCapacity);
         //赋值数组
         System.arraycopy(elementData, 0, newElementData, 0, oldCapacity);
         newElementData[size++] = element;
         elementData = newElementData;
      }

      return true;
   }

remove

remove方法跟ArrayList的区别只要在于

  • ArrayList如果超出了索引的位置那么会直接抛出异常,FastList不会
  • FastList少了结构性modCount的维护

而前面 ConcurrentBag 在遍历的时候为什么要从尾部开始移除,这里也是有设计的,HikariCP认为尾部资源的命中率比较高直接从尾部移除,如果尾部数据直接命中了,那么就少了下面对数组元素的拷贝移动的这一步骤

public T remove(int index)
   {
      if (size == 0) {
         return null;
      }
      //获取到对应索引位的元素
      final T old = elementData[index];
      //获取到当前需要删除元素后面的元素个数
      final int numMoved = size - index - 1;
      if (numMoved > 0) {
         //对元素进行移动
         System.arraycopy(elementData, index + 1, elementData, index, numMoved);
      }
      //将最后一个元素设置为空
      elementData[--size] = null;
      return old;
   }

FastList的源码比较简洁,主要是在于 add方法跟ArrayList的区别,其它的区别就不大

你可能感兴趣的:(java)