Question 7 · Section 4

What is Vector and how does it differ from ArrayList?

Lock Coarsening — JVM optimization that merges several sequential synchronized blocks into one to reduce lock overhead.

Language versions: English Russian Ukrainian

🟢 Junior Level

Vector — legacy version of ArrayList that has been in Java since the beginning.

Key difference:

  Vector ArrayList
Synchronization ✅ All methods synchronized ❌ No
Speed Slower Faster
Resize × 2 × 1.5
When to use Only in legacy code, new code — ArrayList or CopyOnWriteArrayList  

Example:

// ❌ Don't use Vector
Vector<String> v = new Vector<>();  // Slow!

// ✅ Use ArrayList
List<String> list = new ArrayList<>();

Why Vector is slow:

  • Every method = synchronized
  • Even when working in single thread!

🟡 Middle Level

Technical differences

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

// ArrayList:
public boolean add(E e) {  // ← No synchronized!
    modCount++;
    add(e, elementData, size);
    return true;
}

Resize

Vector: capacity × 2
  10 → 20 → 40 → 80
  → Grows fast, more wasted memory

ArrayList: capacity × 1.5
  10 → 15 → 22 → 33
  → More economical, less fragmentation

Why Vector synchronization DOESN’T help

// ❌ Vector NOT thread-safe for compound operations!
if (!vector.contains(obj)) {  // Check
    vector.add(obj);           // ← Another thread can interject!
}

This is called **"check-then-act"** race condition: check (`contains`) and action (`add`)  two separate operations where another thread can interfere.

// Still need external synchronized:
synchronized (vector) {
    if (!vector.contains(obj)) {
        vector.add(obj);
    }
}

Alternatives

// No synchronization:
ArrayList<String> list = new ArrayList<>();

// With synchronization (many reads):
List<String> list = new CopyOnWriteArrayList<>();

// With synchronization (universal):
List<String> list = Collections.synchronizedList(new ArrayList<>());

// For queues:
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

How to choose:

  • Single thread → ArrayList
  • Multi-thread, many reads → CopyOnWriteArrayList
  • Multi-thread, mixed load → Collections.synchronizedList
  • Multi-thread, queue → ConcurrentLinkedQueue

🔴 Senior Level

Lock Contention

100 threads call vector.get(0):
  → All wait for single monitor
  → Serialization → 0 parallelism!

ArrayList:
  → 100 threads read simultaneously
  → Lock-free reading

JIT Lock Coarsening

Lock Coarsening — JVM optimization that merges several sequential synchronized blocks into one to reduce lock overhead.

JVM tries to optimize:
  vector.get(0);
  vector.get(1);
  vector.get(2);

→ Lock Coarsening: one lock for all three
→ But this masks the problem, doesn't solve it!

LSP Violation: Stack extends Vector

LSP (Liskov Substitution Principle) — OOP principle: subclass must be substitutable by base class without breaking correctness. Stack violates this by adding methods incompatible with stack semantics.

// Stack extends Vector!
Stack<String> stack = new Stack<>();
stack.push("A");
stack.add(0, "B");  // ← Breaks stack semantics!

// → Stack can do everything Vector can
// → Violation of Liskov Substitution Principle

Enumeration vs Iterator

// Vector has Enumeration (legacy)
Enumeration<String> e = vector.elements();
while (e.hasMoreElements()) {
    e.nextElement();  // Not fail-fast!
}

// Iterator (modern)
Iterator<String> it = vector.iterator();
// → Fail-fast, like ArrayList

Production Experience

Real case: Vector killed throughput

  • App: 1000 RPS, Vector for logs
  • Lock contention: 80% time on synchronized
  • Solution: ArrayList
  • Result: +400% throughput

Best Practices

  1. DO NOT use Vector — it’s legacy
  2. ArrayList — by default
  3. CopyOnWriteArrayList — for thread-safe
  4. Collections.synchronizedList — universal
  5. ConcurrentLinkedQueue — for queues
  6. Stack → ArrayDeque — for stacks
  7. Enumeration → Iterator — modern

Summary for Senior

  • Vector = legacy, synchronized, slow
  • ArrayList = faster, no synchronization
  • Vector synchronization doesn’t give real thread-safety
  • Lock Contention kills parallelism
  • Resize × 2 → more fragmentation
  • Stack extends Vector = LSP violation
  • CopyOnWriteArrayList = proper thread-safe alternative
  • NEVER use Vector in new code

🎯 Interview Cheat Sheet

Must know:

  • Vector = legacy, all methods synchronized → slow even in single thread
  • Resize: Vector × 2 (more fragmentation) vs ArrayList × 1.5 (more economical)
  • Vector synchronization DOESN’T give real thread-safety for compound operations (race condition “check-then-act”)
  • Lock Contention: 100 threads call vector.get() → serialization → 0 parallelism
  • Stack extends Vector = LSP violation — can call get(index), breaking LIFO semantics
  • Enumeration (Vector) is legacy → use Iterator (fail-fast)
  • Alternatives: ArrayList (single thread), CopyOnWriteArrayList (many reads), Collections.synchronizedList (universal)
  • Real case: Vector → ArrayList replacement gave +400% throughput

Common follow-up questions:

  • Why doesn’t synchronized in Vector guarantee thread-safety? — Compound operations (check-then-act) still need external synchronized
  • What is LSP violation in Stack context? — Stack extends Vector, can call add(0,e) — breaks LIFO
  • When does JIT Lock Coarsening mask the problem? — Merges sequential synchronized blocks, but doesn’t solve lock contention
  • How is CopyOnWriteArrayList better than Vector? — Copy on write, lock-free reading, better for “many reads, few writes” scenarios

Red flags (NOT to say):

  • ❌ “Vector — thread-safe replacement for ArrayList” — synchronized doesn’t give real thread-safety for compound operations
  • ❌ “Vector × 2 resize better than ArrayList × 1.5” — opposite, more fragmentation and wasted memory
  • ❌ “Use Stack as stack” — Stack extends Vector, use ArrayDeque
  • ❌ “Enumeration better than Iterator” — Enumeration is legacy, not fail-fast

Related topics:

  • [[What is Stack]]
  • [[What is the difference between ArrayList and LinkedList]]
  • [[What are the main Collection Framework interfaces]]
  • [[What is Deque]]