首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java Vector 源碼深度解析:線程安全動態數組原理與性能優化

     編輯:Java 程式設計入門

Vector 核心定位

Vector 是 JDK 1.0 早期提供的線程安全動態數組,繼承 AbstractList,實現 List、RandomAccess、Cloneable、Serializable。關鍵特性:

  • 同步方法:所有公共方法均加 synchronized,保證線程安全。
  • 隨機訪問:實現 RandomAccess,下標訪問 O(1)。
  • 擴容策略:默認初始容量 10,擴容倍數由 capacityIncrement 決定(>0 按增量,≤0 翻倍)。
  • 不支援序列化:早期版本未實現 Serializable,現代 JDK 已補全。

繼承體系與存儲結構

Vector 繼承關系 Vector 與 Collection 關系

底層由 Object[] elementData 存儲數據,elementCount 記錄實際大小,capacityIncrement 控制擴容步長。

源碼核心方法剖析

構造函數與擴容邏輯

public Vector() { this(10); }
public Vector(int initialCapacity) { this(initialCapacity, 0); }
public Vector(int initialCapacity, int capacityIncrement) {
    if (initialCapacity < 0) throw new IllegalArgumentException();
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}

private void ensureCapacityHelper(int minCapacity) {
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        int newCapacity = (capacityIncrement > 0) 
            ? oldCapacity + capacityIncrement 
            : oldCapacity * 2;
        if (newCapacity < minCapacity) newCapacity = minCapacity;
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

ensureCapacityHelper 為核心擴容入口,add/insert 操作前均調用。

寫入操作(同步保護)

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

public synchronized void addElement(E obj) { // 歷史兼容方法
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;
}

public synchronized void insertElementAt(E obj, int index) {
    modCount++;
    if (index > elementCount) throw new ArrayIndexOutOfBoundsException();
    ensureCapacityHelper(elementCount + 1);
    System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
    elementData[index] = obj;
    elementCount++;
}

所有修改操作均 synchronized,並更新 modCount 支持 Fail-Fast 迭代器。

刪除與查找

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

public synchronized int indexOf(Object o, int index) {
    if (o == null) {
        for (int i = index; i < elementCount; i++) if (elementData[i] == null) return i;
    } else {
        for (int i = index; i < elementCount; i++) if (o.equals(elementData[i])) return i;
    }
    return -1;
}

迭代器與 Enumeration

Vector 提供兩種遍歷接口:

  • Iterator:繼承自 AbstractList,內部類 Itr 實現 Fail-Fast。
  • Enumeration elements():歷史接口,匿名類實現,同步塊保護 nextElement()。

四種遍歷方式性能實測

// 測試環境:JDK 8, 100,000 元素
Vector<Integer> vec = new Vector<>();
for (int i = 0; i < 100000; i++) vec.add(i);

// 1. 隨機訪問(推薦)
for (int i = 0, n = vec.size(); i < n; i++) vec.get(i);          // 6 ms

// 2. Iterator
for (Iterator<Integer> it = vec.iterator(); it.hasNext(); ) it.next(); // 9 ms

// 3. 增強 for(語法糖,底層 Iterator)
for (Integer v : vec) { }                                           // 8 ms

// 4. Enumeration
for (Enumeration<Integer> e = vec.elements(); e.hasMoreElements(); ) e.nextElement(); // 7 ms
方式耗時推薦指數說明
隨機訪問 get(i)6 ms⭐⭐⭐⭐⭐實現 RandomAccess,無額外對象創建,JIT 優化最佳
Enumeration7 ms⭐⭐⭐歷史接口,同步開銷略大
增強 for8 ms⭐⭐⭐編譯為 Iterator,語法簡潔
Iterator9 ms⭐⭐Fail-Fast 檢查 modCount 有微小開銷

結論:Vector 實現 RandomAccess,優先使用下標遍歷,避免迭代器開銷。

Vector vs ArrayList 選型指南

維度VectorArrayList
線程安全方法級同步非線程安全
擴容策略可配置增量/翻倍固定 1.5 倍
性能(單線程)同步開銷大輕量快速
序列化支持支持
適用場景舊代碼維護、簡單多線程現代首選、高性能
⚠ 避坑提示:Vector 的同步粒度較粗,複雜併發場景下仍需外部加鎖(如批量操作、複合動作)。高併發推薦 CopyOnWriteArrayList 或 Collections.synchronizedList(new ArrayList<>()) 配合顯式鎖。

實戰示例

Vector<String> vec = new Vector<>(20, 5); // 初始 20,每次增 5
vec.add("1"); vec.add("2"); vec.add("3");
vec.set(0, "100");           // 修改
vec.add(2, "300");           // 插入
System.out.println(vec);     // [100, 2, 300, 3]

System.out.println(vec.indexOf("100"));      // 0
System.out.println(vec.lastIndexOf("100"));  // 0
System.out.println(vec.firstElement());      // 100
System.out.println(vec.elementAt(2));        // 300
System.out.println(vec.capacity());          // 20
System.out.println(vec.size());              // 4

// 截取子列表(線程安全視圖)
List<String> sub = vec.subList(1, 3);        // [2, 300]

// 保留交集
Vector<String> retain = new Vector<>();
retain.add("100"); retain.add("300");
vec.retainAll(retain);                       // vec 變為 [100, 300]

// 轉數組
String[] arr = vec.toArray(new String[0]);
vec.clear();
System.out.println(vec.isEmpty());           // true

總結

  • Vector 以 synchronized 實現線程安全,適合低併發、舊系統維護。
  • 擴容策略可通過構造函數調優,避免頻繁擴容抖動。
  • 遍歷強烈建議下標隨機訪問,充分利用 RandomAccess 特性。
  • 新項目優先選 ArrayList + 顯式同步或並發容器,Vector 逐漸邊緣化。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved