美文网首页
Java Vector源码学习

Java Vector源码学习

作者: 梦工厂 | 来源:发表于2018-03-07 16:28 被阅读59次

    Vector

    public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable


    一:自动扩容机制

    The Vector class implements a growable array of objects. Like an array, it contains components that can be accessed using an integer index. However, the size of a Vector can grow or shrink as needed to accommodate adding and removing items after the Vector has been created.

    1. 初始化

      底层为对象数组protected Object[] elementData;

      protected int elementCount; 元素个数

      protected int capacityIncrement;增长个数

          public Vector(int initialCapacity, int capacityIncrement) {
              super();
              if (initialCapacity < 0)
                  throw new IllegalArgumentException("Illegal Capacity: "+
                                                     initialCapacity);
              this.elementData = new Object[initialCapacity];
              this.capacityIncrement = capacityIncrement;
          }
      
          public Vector(int initialCapacity) {
              this(initialCapacity, 0);
          }
      
          public Vector() {
              this(10);
          }
      
    2. add

      public synchronized boolean add(E e) {
          modCount++;
          ensureCapacityHelper(elementCount + 1);
          elementData[elementCount++] = e;
          return true;
      }
      

      判断是否分配

      private void ensureCapacityHelper(int minCapacity) {
          // overflow-conscious code
          if (minCapacity - elementData.length > 0)
              grow(minCapacity);
      }
      

      关键:capacityIncrement》0时,每次增长capacityIncrement个元素;

      ​ capacityIncrement《=0时,2倍扩增;

      private void grow(int minCapacity) {
          // overflow-conscious code
          int oldCapacity = elementData.length;
          int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                           capacityIncrement : oldCapacity);
          if (newCapacity - minCapacity < 0)
              newCapacity = minCapacity;
          if (newCapacity - MAX_ARRAY_SIZE > 0)
              newCapacity = hugeCapacity(minCapacity);
          elementData = Arrays.copyOf(elementData, newCapacity);
      }
      
    3. remove: 并不会调节底层数组的大小

      public synchronized E remove(int index) {
          modCount++;
          if (index >= elementCount)
              throw new ArrayIndexOutOfBoundsException(index);
          E oldValue = elementData(index);
      
          int numMoved = elementCount - index - 1;
          if (numMoved > 0)
              System.arraycopy(elementData, index+1, elementData, index,
                               numMoved);
          elementData[--elementCount] = null; // Let gc do its work
      
          return oldValue;
      }
      

      clear实现

      public synchronized void removeAllElements() {
          modCount++;
          // Let gc do its work
          for (int i = 0; i < elementCount; i++)
              elementData[i] = null;
      
          elementCount = 0;
      }
      

      真正减少底层数组容量

      public synchronized void trimToSize() {
          modCount++;
          int oldCapacity = elementData.length;
          if (elementCount < oldCapacity) {
              elementData = Arrays.copyOf(elementData, elementCount);
          }
      }
      

    二:线程安全

    jdk1.0 Vector ,jdk1.2 ArrayList

    Vector 将可变状态封装在对象内部,通过对象锁对所有访问可变状态的代码进行同步,使得在该对象上不会发生并发访问。

    对比ArrayList可以发现,增删改查所有方法都加了synchronized 关键字。

        public synchronized int size() {
            return elementCount;
        }
    

    三: Fail-Fast 机制

    Vector返回的Iterator也是fail-fast。

    public synchronized Iterator<E> iterator() {
      return new Itr();
    }
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;
    
        public boolean hasNext() {
            // Racy but within spec, since modifications are checked
            // within or after synchronization in next/previous
            return cursor != elementCount;
        }
        public E next() {
            synchronized (Vector.this) {
                checkForComodification();
                int i = cursor;
                if (i >= elementCount)
                    throw new NoSuchElementException();
                cursor = i + 1;
                return elementData(lastRet = i);
            }
        }
    }
    

    Vector创建了Iterator之后,进行增删操作,modCount变化。-》ConcurrentModificationException


    四:总结

    1. Vector的问题

      1)过多的同步,每个方法都有synchronized;

      2)复合操作,并不安全,需要额外加锁。

      if(!vector.contains(e)){
        vector.add(e);
      }
      
    2. Vector vs ArrayList

      1. ArrayList扩增方式为1.5倍。

        Vector扩容方式可以自设每次加几个,或者默认2倍扩容。

      2. Vector线程安全

        ArrayList线程不安全

      3. Vector 为jdk1.0版本,并不推荐;

        不需要线程安全时,推荐选择ArrayList;

        需要线程安全时,List list = Collections.synchronizedList(new ArrayList(...));

        Collections.synchronizedList虽然在增删改查方法都有synchronized;但是有好处;

        (1) Vector 同步方法加锁的是this对象,没办法控制锁定的对象。

        SynchronizedList的同步,使用的是synchronized代码块对mutex对象加锁,这个mutex对象还能够通过构造函数传进来,也就是说我们可以指定锁定的对象。

        (2)对于迭代需要加大锁,Iterator.remove()的小锁并不需要,额外开销;synchronizedList.iterator()没synchronized关键字,自己加大锁,Iterator.remove()没有锁;

        // 对迭代过程加锁
                synchronized (vector) {
                    for (Integer i : vector) {
                    }
                }
        

    @梦工厂 2018.3.7

    相关文章

      网友评论

          本文标题:Java Vector源码学习

          本文链接:https://www.haomeiwen.com/subject/kwajfftx.html