【发布时间】:2015-09-25 23:20:22
【问题描述】:
我有以下课程:
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);
}
我认为避免并发访问就足够了,但我得到了这个错误:
HashMap.java
checkConcurrentMod
java.util.HashMap$AbstractMapIterator
java.util.ConcurrentModificationException
Unhandled exception in plugin method
java.util.ConcurrentModificationException
我有 10 个线程在使用这个类,它大约每 100.000 次调用就会引发一次这个错误。
这个单例有什么问题?
【问题讨论】:
-
完整的堆栈跟踪以及您看到发生此异常的代码?
-
你会同步课堂内地图上的调用吗?也许这些访问可能会导致问题?
-
我发现了问题。其中一个函数(此处未写)试图访问与 get 实例相同的对象。这两个函数是单独同步的,但可以同时调用为了解决这个问题,我将其更改为 ConcurrentHashMap,并且我还通过使用双重检查锁定改进了同步。现在我会整晚运行测试,让你知道问题是否真的解决了
标签: java multithreading hashmap singleton synchronized