The problem is that the first map.put (..) is not synchronized. Either synchronize it, or use Collections.synchronizedMap(..) . Test case:
import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Random; public class Test { public static void main(String... args) throws InterruptedException { final Random random = new Random(); final int max = 10; for (int j = 0; j < 100000; j++) { // final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<String, Integer>()); final HashMap<String, Integer> map = new HashMap<String, Integer>(); Thread t = new Thread() { public void run() { for (int i = 0; i < 100; i++) { incrementCountInMap(map, random.nextInt(max)); } } }; t.start(); for (int i = 0; i < 100; i++) { incrementCountInMap(map, random.nextInt(max)); } t.join(); if (map.size() != max) { System.out.println("size: " + map.size() + " entries: " + map); } } } static void incrementCountInMap(Map<String, Integer> map, int id) { String key = "k" + id; if (map.get(key) == null) { map.put(key, 0); } synchronized (map) { map.put(key, map.get(key).intValue() + 1); } } }
Some results that I get:
size: 11 entries: {k3=24, k4=20, k5=16, k6=30, k7=16, k8=18, k9=11, k0=18, k1=16, k1=13, k2=18} size: 11 entries: {k3=18, k4=19, k5=21, k6=20, k7=18, k8=26, k9=20, k0=16, k1=25, k2=15} size: 11 entries: {k3=25, k4=20, k5=27, k6=15, k7=17, k8=17, k9=24, k0=21, k1=16, k1=1, k2=17} size: 11 entries: {k3=13, k4=21, k5=18, k6=21, k7=13, k8=17, k9=25, k0=20, k1=23, k2=28} size: 11 entries: {k3=21, k4=25, k5=19, k6=12, k7=17, k8=14, k9=23, k0=24, k1=26, k2=18} size: 9 entries: {k3=13, k4=17, k5=23, k6=24, k7=18, k8=19, k9=28, k0=21, k1=17, k2=20} size: 9 entries: {k3=15, k4=24, k5=21, k6=18, k7=21, k8=30, k9=20, k0=17, k1=15, k2=19} size: 11 entries: {k3=15, k4=13, k5=21, k6=21, k7=15, k8=19, k9=23, k0=30, k1=15, k2=27} size: 11 entries: {k3=29, k4=15, k5=19, k6=19, k7=15, k8=23, k9=14, k0=31, k1=18, k2=12} size: 11 entries: {k3=17, k4=18, k5=20, k6=11, k6=13, k7=20, k8=22, k9=30, k0=12, k1=21, k2=16}