FastList源码
FastList 是 HikariCP 中设计的本地资源列表获取资源,下面是源码的分析
属性
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的区别,其它的区别就不大