Reputation: 802
I have a situation where I have a huge map where i maintain some data. My application is multi threaded.
One thread might try to remove entries from the map and the second thread may try to copy the map. Following is the sample code that depicts my problem.
public class CollectionsTest {
static Map<String, String> map = new HashMap<>();
public static void main(String [] args) throws InterruptedException {
for(long i=0;i<1000000; i++){
map.put("key"+i, "value"+i);
}
Thread t1 = new Thread(new Task1());
Thread t2 = new Thread(new Task2());
t1.start();
t2.start();
t1.join();
t2.join();
}
private static class Task1 implements Runnable {
@Override
public void run() {
System.out.println("Task 1 start");
Map<String, String> copy = new HashMap<>(map);
System.out.println(copy.get("key1"));
System.out.println("Task 1 done");
}
}
private static class Task2 implements Runnable {
@Override
public void run() {
System.out.println("Task 2 start");
map.remove("key2");
System.out.println("Task 2 end");
}
}
}
Following is the output
Task 1 start
Task 2 start
Task 2 end
Exception in thread "Thread-0" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$EntryIterator.next(HashMap.java:1463)
at java.util.HashMap$EntryIterator.next(HashMap.java:1461)
at java.util.HashMap.putMapEntries(HashMap.java:511)
at java.util.HashMap.<init>(HashMap.java:489)
at com.alcatel.pma.core.configmgmt.CollectionsTest$Task1.run(CollectionsTest.java:27)
at java.lang.Thread.run(Thread.java:745)
Process finished with exit code 0
What is the best way to avoid this situation?
Upvotes: 1
Views: 485
Reputation: 2122
You basically have two options when dealing with data structures in a multi-threaded environment.
You choose a synchronized implementation like ConcurrentHashMap, CopyOnWriteArray etc. These data structures are meant to be used concurrently. Implementation details vary significantly (data cloning on write, locks/semaphores, monitors (synchronized keyword) and you have to chose with care what structure is most suitable.
You synchronize access to your unsynhronized data structure using locks (ReentrandRead/WriteLock) or Java monitors.
If you don't know much about concurrency it is advisable to go with option number one. If you want to learn a lot about Java programming, go with option two.
Upvotes: 2