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

Java Vector 類深度解析:核心操作、擴容機制與線程安全陷阱

     編輯:Java 相關知識

Vector 基本操作示例

Vector 為 JDK 1.0 即存在的動態陣列,底層由 Object[] 實現,所有方法均以 synchronized 修飾,號稱「線程安全」。

Vector v1 = new Vector();
v1.addElement("one");
v1.addElement(new Integer(1));
v1.insertElement("three", 2);     // 指定位置插入
v1.setElementAt("four", 2);       // 指定位置替換
v1.removeElement(integer1);       // 移除第一個匹配元素
Enumeration enum = v1.elements(); // 迭代遍歷
System.out.println(v1.indexOf(integer1));   // 正向查找索引
System.out.println(v1.lastIndexOf(integer1)); // 反向查找索引
v1.setSize(4);                    // 截斷/擴展大小

擴容機制:1 倍增長策略

不同於 ArrayList 的 1.5 倍擴容,Vector 預設採用 1 倍擴容(即容量翻倍):

protected int capacityIncrement; // 可指定增量,預設 0 表示翻倍
private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
    // ... 邊界檢查與複製
}

若建構時指定 capacityIncrement,則按指定增量擴容;否則預設翻倍。

線程安全的誤區與實測

雖然所有公共方法皆加 synchronized,但在複合操作(如「判斷大小 → 獲取/移除」)下仍不安全:

// 多線程併發測試
private static Vector<Integer> vector = new Vector<>();
public static void main(String[] args) {
    while (true) {
        for (int i = 0; i < 10; i++) vector.add(i);
        new Thread(() -> {
            for (int i = 0; i < vector.size(); i++) vector.remove(i);
        }).start();
        new Thread(() -> {
            for (int i = 0; i < vector.size(); i++) System.out.println(vector.get(i));
        }).start();
        // 短時間內拋出 ArrayIndexOutOfBoundsException
    }
}

原因:size()、get()、remove() 雖各自同步,但組合操作非原子。線程 A 刪除索引 i 後,線程 B 仍嘗試訪問原索引 i,導致越界。

正確做法

  • 在呼叫端以 synchronized(vector) 包裹複合操作。
  • 或改用 Collections.synchronizedList(new ArrayList<>()) 並同步複合操作。
  • 高併發場景推薦 CopyOnWriteArrayList 或並發佇列。

總結

Vector 的「線程安全」僅限單一方法層面,複合業務邏輯仍需外部同步。現代開發多傾向 ArrayList + 顯式同步或並發容器,Vector 已逐漸淡出主流。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved