Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java synchronizedList iteration: hold the wrapper lock

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

Collections.synchronizedList serializes individual calls, but a compound iteration still needs a caller-held lock on the wrapper.

This complete Java 8 program has a checked output. Compile it as the named public class, then run it without additional libraries.

The lock covers the whole traversal

A worker may mutate a shared list between the iterator's next calls even when every individual list operation is synchronized. The caller must synchronize on the returned wrapper while iterating. Synchronizing on the original backing list is a different monitor and does not coordinate with the wrapper.

The fixture does not start a competing thread. It demonstrates the required monitor placement and a stable sum in a single process; it is not evidence that a production workload avoids contention or starvation.

Prefer a clearer ownership model when possible

A copied snapshot avoids holding a shared lock during slow processing, but it is stale as soon as the copy finishes and shares mutable element objects. A concurrent queue or a single owning worker may make the application contract easier to reason about. View and snapshot ownership covers that distinction.

Working program

Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SharedReceiptBatchRead {
    public static void main(String[] args) {
        List<Integer> amounts = Collections.synchronizedList(new ArrayList<>());
        amounts.add(12); amounts.add(18);
        int total = 0;
        synchronized (amounts) {
            for (int amount : amounts) total += amount;
        }
        System.out.println("total=" + total);
    }
}

Output

Output
total=30

Costs and boundaries

A full protected traversal is O(n) and keeps the monitor for its duration. Concurrent writers wait for that lock; the code provides mutual exclusion, not parallel read scalability or a durable snapshot.

Common Mistakes

  • Do not rely on synchronized individual calls to make a multi-call loop atomic.
  • Do not lock the unsynchronized backing list instead of the wrapper.
  • Do not run blocking network work while holding the list lock.

Read next

Java LinkedList: operations, internals and failure cases, Java Iterator and ListIterator: traversal and controlled edits, Java collection views: live wrappers, snapshots and shallow copies.

Collection views and copy boundaries

Continue with Collections.unmodifiableList is a live view, not a snapshot, List.copyOf freezes container membership but not mutable elements.

java
synchronized-list-iteration
Storage details