ArrayList

构造器

  1. 参数:
  2. initialCapacity 列表的初始容量
  3. 抛出:
  4. IllegalArgumentException 如果指定的初始容量为负
  5. public ArrayList(int initialCapacity) {
  6. if (initialCapacity > 0) {
  7. this.elementData = new Object[initialCapacity];
  8. } else if (initialCapacity == 0) {
  9. this.elementData = EMPTY_ELEMENTDATA;
  10. } else {
  11. throw new IllegalArgumentException("Illegal Capacity: "+
  12. initialCapacity);
  13. }
  14. }

Add及扩容方法

  1. public boolean add(E e) {
  2. // 新增size,及扩容操作
  3. ensureCapacityInternal(size + 1); // Increments modCount!!
  4. // 赋值
  5. elementData[size++] = e;
  6. return true;
  7. }
  8. private void ensureCapacityInternal(int minCapacity) {
  9. // 第 n+1 个元素
  10. ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
  11. }
  12. private void ensureExplicitCapacity(int minCapacity) {
  13. modCount++;
  14. // 如果但你过去长度大于数组的长度,进行扩容
  15. if (minCapacity - elementData.length > 0)
  16. grow(minCapacity);
  17. }
  18. // 扩容方法
  19. private void grow(int minCapacity) {
  20. // 旧容量大小
  21. int oldCapacity = elementData.length;
  22. // 新容量大小 >> 1 正数的右移后面的值,代表除以2 的 几次方
  23. int newCapacity = oldCapacity + (oldCapacity >> 1);
  24. if (newCapacity - minCapacity < 0)
  25. newCapacity = minCapacity;
  26. if (newCapacity - MAX_ARRAY_SIZE > 0)
  27. newCapacity = hugeCapacity(minCapacity);
  28. // 复制
  29. elementData = Arrays.copyOf(elementData, newCapacity);
  30. }

其他

  1. // 检查下标是否越界
  2. private void rangeCheck(int index) {
  3. if (index >= size)
  4. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  5. }
  6. // get 方法
  7. public E get(int index) {
  8. rangeCheck(index);
  9. return elementData(index);
  10. }
  11. // set 方法
  12. public E set(int index, E element) {
  13. rangeCheck(index);
  14. E oldValue = elementData(index);
  15. elementData[index] = element;
  16. return oldValue;
  17. }
  18. // 移除元素
  19. public E remove(int index) {
  20. rangeCheck(index);
  21. // “a”,”b”,c”,”d”,”e”
  22. modCount++;
  23. E oldValue = elementData(index);
  24. // 获取该元素的
  25. int numMoved = size - index - 1;
  26. if (numMoved > 0)
  27. System.arraycopy(elementData, index+1, elementData, index,
  28. numMoved);
  29. elementData[--size] = null; // clear to let GC do its work
  30. return oldValue;
  31. }

ReentrantLock解析

想要了解reentrantLock 那么就必须知道Lock 接口都抽象了哪些接口。

  1. // 顶层抽象
  2. public interface Lock {
  3. // 直接加锁
  4. void lock();
  5. // 加锁中断
  6. void lockInterruptibly() throws InterruptedException;
  7. // 尝试加锁
  8. boolean tryLock();
  9. // 尝试加锁
  10. boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
  11. // 解锁
  12. void unlock();
  13. // condition 的玩法
  14. Condition newCondition();
  15. }

ReentrantLock的实现

同步器AbstractQueuedSynchronizer

同步器的开始提到了其实现依赖于一个FIFO队列,那么队列中的元素Node就是保存着线程引用和线程状态的容器,每个线程对同步器的访问,都可以看做是队列中的一个节点。Node的主要包含以下成员变量:

  1. Node {
  2. int waitStatus;
  3. Node prev;
  4. Node next;
  5. Node nextWaiter;
  6. Thread thread;
  7. }

上面属性解释:

属性名称 描述
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 入队列时的当前线程。

自定义锁

  1. // 加锁
  2. public final void acquire(int arg) {
  3. if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
  4. selfInterrupt();
  5. }