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.