jde*_*del 6 java singleton multithreading hashmap synchronized
我有以下课程:
public class AggregationController {
private HashMap<String, TreeMap<Integer, String>> messages;
private HashMap<String, Integer> counters;
Boolean buildAggregateReply;
private boolean isAggregationStarted;
private static HashMap<String, AggregationController> instances = new HashMap<String, AggregationController>();
private AggregationController() throws MbException{
messages = new HashMap<String, TreeMap<Integer,String>>();
counters = new HashMap<String, Integer>();
buildAggregateReply = true;
isAggregationStarted = false;
}
public static synchronized AggregationController getInstance(String id) throws MbException{
if(instances.get(id) == null)
instances.put(id, new AggregationController());
return instances.get(id);
}
Run Code Online (Sandbox Code Playgroud)
我认为这足以避免并发访问,但我收到了这个错误:
HashMap.java
checkConcurrentMod
java.util.HashMap$AbstractMapIterator
java.util.ConcurrentModificationException
Unhandled exception in plugin method
java.util.ConcurrentModificationException
Run Code Online (Sandbox Code Playgroud)
我有10个线程使用这个类,它每100次调用大约抛出一次这个错误.
这个单身人士怎么了?
问题很简单 HashMap不是线程安全的,正如您可以在链接的文档中阅读的那样。
你应该尝试将它们更改为ConcurrentHashMaps。
除此之外,您还应该更改单例实现以更好地处理多线程。维基百科页面上关于双重检查锁定的提供了很多很好的示例。
ps:不应该将变量声明为 HashMap,而应该将它们声明为 Map。这样您就可以非常轻松地更改具体实现,而无需重构任何内容。这称为接口编程。