ArrayList
构造器
参数:
initialCapacity – 列表的初始容量
抛出:
IllegalArgumentException – 如果指定的初始容量为负
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
Add及扩容方法
public boolean add(E e) {
// 新增size,及扩容操作
ensureCapacityInternal(size + 1); // Increments modCount!!
// 赋值
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
// 第 n+1 个元素
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 如果但你过去长度大于数组的长度,进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
// 扩容方法
private void grow(int minCapacity) {
// 旧容量大小
int oldCapacity = elementData.length;
// 新容量大小 >> 1 正数的右移后面的值,代表除以2 的 几次方
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 复制
elementData = Arrays.copyOf(elementData, newCapacity);
}
其他
// 检查下标是否越界
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// get 方法
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
// set 方法
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
// 移除元素
public E remove(int index) {
rangeCheck(index);
// “a”,”b”,c”,”d”,”e”
modCount++;
E oldValue = elementData(index);
// 获取该元素的
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
ReentrantLock解析
想要了解reentrantLock 那么就必须知道Lock 接口都抽象了哪些接口。
// 顶层抽象
public interface Lock {
// 直接加锁
void lock();
// 加锁中断
void lockInterruptibly() throws InterruptedException;
// 尝试加锁
boolean tryLock();
// 尝试加锁
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 解锁
void unlock();
// condition 的玩法
Condition newCondition();
}
ReentrantLock的实现
同步器AbstractQueuedSynchronizer
同步器的开始提到了其实现依赖于一个FIFO队列,那么队列中的元素Node就是保存着线程引用和线程状态的容器,每个线程对同步器的访问,都可以看做是队列中的一个节点。Node的主要包含以下成员变量:
Node {
int waitStatus;
Node prev;
Node next;
Node nextWaiter;
Thread thread;
}
上面属性解释:
属性名称 | 描述 |
---|---|
int waitStatus | 表示节点的状态。其中包含的状态有: 1. CANCELLED,值为1,表示当前的线程被取消; 2. SIGNAL,值为-1,表示当前节点的后继节点包含的线程需要运行,也就是unpark; 3. CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队列中; 4. PROPAGATE,值为-3,表示当前场景下后续的acquireShared能够得以执行; 5. 值为0,表示当前节点在sync队列中,等待着获取锁。 |
Node prev | 前驱节点,比如当前节点被取消,那就需要前驱节点和后继节点来完成连接。 |
Node next | 后继节点。 |
Node nextWaiter | 存储condition队列中的后继节点。 |
Thread thread | 入队列时的当前线程。 |
自定义锁
// 加锁
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}