I am trying to evaluate these concepts using code. This is what I ended up with
public void runCWith3Threads() {
for (int i = 0; i < 10; i++) {
Map<Integer, Person> shm = Collections.synchronizedMap(new HashMap<Integer, Person>());
Map<Integer, Person> chm = new ConcurrentHashMap<Integer, Person>();
MapThread sm1 = new MapThread(shm, 0, 20000, "sm1");
MapThread sm2 = new MapThread(shm, 20000, 30000, "sm2");
MapThread sm3 = new MapThread(shm, 30000, 50000, "sm3");
sm1.start();sm2.start();sm3.start();
while (true) {
try {
sm1.join();
sm2.join();
sm3.join();
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long secondMax = sm1.time > sm2.time ? sm1.time : sm2.time;
long firstMax = secondMax > sm3.time ? secondMax : sm3.time;
System.out.println("Millisec of SynchronizedMap cost: " + firstMax);
MapThread m1 = new MapThread(chm, 0, 20000, "m1");
MapThread m2 = new MapThread(chm, 20000, 30000, "m2");
MapThread m3 = new MapThread(chm, 30000, 50000, "m3");
m1.start();m2.start();m3.start();
while (true) {
try {
m1.join();
m2.join();
m3.join();
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
secondMax = m1.time > m2.time ? m1.time : m2.time;
firstMax = secondMax > m3.time ? secondMax : m3.time;
System.out.println("Millisec of ConcurrentHashMap cost: " + firstMax);
System.out.println();
}
}
public class MapThread extends Thread {
Map<Integer, Person> map;
int from;
int to;
long time;
String name;
public MapThread(Map<Integer, Person> map, int from, int to, String name) {
this.map = map;
this.from = from;
this.to = to;
this.name = name;
}
public void run() {
long start = System.currentTimeMillis();
for (int i = from; i < to; i++) {
map.put(i, new Person());
}
long end = System.currentTimeMillis();
time = end - start;
return;
}
}
I expect that after running the code, the result ConcurrentHashMapwill be faster, since it allows multiple insertion into the map. For SynchronizedMap, since each thread is waiting for the completion of the previous thread (the card is synchronized), the code will act just as it will work with one thread environment
However, the result does not fully reflect what I expected
Millisec of SynchronizedMap cost: 250
Millisec of ConcurrentHashMap cost: 203
Millisec of SynchronizedMap cost: 171
Millisec of ConcurrentHashMap cost: 172
Millisec of SynchronizedMap cost: 172
Millisec of ConcurrentHashMap cost: 188
Millisec of SynchronizedMap cost: 171
Millisec of ConcurrentHashMap cost: 172
Millisec of SynchronizedMap cost: 187
Millisec of ConcurrentHashMap cost: 172
Millisec of SynchronizedMap cost: 171
Millisec of ConcurrentHashMap cost: 189
Millisec of SynchronizedMap cost: 187
Millisec of ConcurrentHashMap cost: 171
Millisec of SynchronizedMap cost: 188
Millisec of ConcurrentHashMap cost: 171
Millisec of SynchronizedMap cost: 172
Millisec of ConcurrentHashMap cost: 172
Millisec of SynchronizedMap cost: 171
Millisec of ConcurrentHashMap cost: 188
Why is this?
Update
Map<Integer, Person> chm = new ConcurrentHashMap<Integer, Person>(100000, 10, 3);
I have a result
Millisec of SynchronizedMap cost: 208
Millisec of ConcurrentHashMap cost: 216
Millisec of SynchronizedMap cost: 255
Millisec of ConcurrentHashMap cost: 196
Map<Integer, Person> chm = new ConcurrentHashMap<Integer, Person>(100000);
I have a result
Millisec of SynchronizedMap cost: 204
Millisec of ConcurrentHashMap cost: 283
Millisec of SynchronizedMap cost: 203
Millisec of ConcurrentHashMap cost: 200