MSR MSR - 1 year ago 42
Java Question

Executor Service clear map values in multithreading environment

i have a situation here. I am using Executor Service for making use of multithreading. So now i am trying to add a value to a map and clear it for each thread as soon as i am done with that loop. I have wrote the below code for that.

I have created a map, and saving the value for each iteration and clearing it. But as i am using Executor Service its creating 10thread and adding the value to the map i believe. thats why i am able to see multiple values even i am just adding one value and clearing it.

So how do i clear the map each trasaction in the loop :(

Code:

public class Test1 {
public static void main(String[] args){
ExecutorService executor = Executors.newFixedThreadPool(10);
final Multimap<Object, Object> map = Multimaps.synchronizedMultimap(ArrayListMultimap.create());

final List<String> listA = new ArrayList<String>();
listA.add("e");
listA.add("f");
listA.add("g");
final List<String> listB = new ArrayList<String>();
listB.add("e");
listB.add("f");
listB.add("g");
final List<String> listC = new ArrayList<String>();
listC.add("e");
listC.add("f");
listC.add("g");


for (final String stateId : listA) {
for (final String gradeList : listB) {
for (final String subjectList : listC) {
executor.execute(new Runnable() {
@Override
public void run() {
map.clear();
map.put("f", "hi");
System.out.println("map before "+map);

System.out.println("map after "+map);
}
});
}

}
}
executor.shutdown();
try {
executor.awaitTermination(24L, TimeUnit.HOURS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}

output:

map before {f=[hi, hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi, hi]}
map before {f=[hi, hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi, hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}

Answer Source

Simple - the javadoc clearly states:

This class is not threadsafe when any concurrent operations update the multimap. Concurrent read operations will work correctly. To allow concurrent update operations, wrap your multimap with a call to Multimaps.synchronizedListMultimap(com.google.common.collect.ListMultimap).

In other words: you can't just take any convenient collection class and throw multiple threads at it - without further precautions.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download