Skip to content
All Posts

Demonstrating That ArrayList and HashMap Are Not Thread-Safe

Reproducible Java examples that expose ArrayList and HashMap failures when multiple threads modify them concurrently.

ArrayList and HashMap do not synchronize concurrent writes. A simple way to demonstrate the problem is to start several threads, let each thread add a known number of entries, wait for them to finish, and compare the expected size with the actual size.

List<Integer> values = new ArrayList<Integer>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(() -> {
for (int j = 0; j < 1000; j++) values.add(j);
});
threads.add(thread);
thread.start();
}
for (Thread thread : threads) thread.join();
System.out.println(values.size());

The expected result is 100,000, but lost updates or internal-state races can produce a smaller value or an exception. Replacing the list with a shared HashMap and concurrently inserting distinct keys demonstrates the same class of problem.

Use synchronization or a collection designed for concurrency, such as ConcurrentHashMap, when multiple threads mutate shared data. The exact replacement for ArrayList depends on the workload; copying, locking, or redesigning ownership may be more appropriate than choosing a concurrent collection mechanically.


Originally published on SegmentFault.