Java ConcurrentHashMap中的值引发NullPointerException
我正在维护使用Java ConcurrentHashMap中的值引发NullPointerException,java,concurrency,nullpointerexception,Java,Concurrency,Nullpointerexception,我正在维护使用ConcurrentHashMap的多线程遗留代码 其他方法中有添加和删除操作 在下面的代码中,在从映射中收集了一些值之后的某个时刻,它在执行同步(值)时抛出NullPointerException 执行时,objId不再存在,并且mapsList添加null,因此,在第二个循环中抛出NullPoinerException 出现此异常还有其他原因吗?您已被检查失败,请按反模式操作。它意味着检查一个条件(如存在一个键),然后对其进行操作(如调用get),忽略条件可能在两者之间发生变化
ConcurrentHashMap
的多线程遗留代码
其他方法中有添加和删除操作
在下面的代码中,在从映射中收集了一些值之后的某个时刻,它在执行同步(值)
时抛出NullPointerException
执行时,objId
不再存在,并且mapsList
添加null,因此,在第二个循环中抛出NullPoinerException
出现此异常还有其他原因吗?您已被检查失败,请按反模式操作。它意味着检查一个条件(如存在一个键),然后对其进行操作(如调用
get
),忽略条件可能在两者之间发生变化的可能性
因此,在迭代conMap.keySet()
时,您会遇到一个特定的键,但在调用conMap.get(objId)
时,该键可能不再位于映射中,返回null
会报告该键
强烈建议使用具有合适的hashCode
/equals
实现的键类型,因此您不需要迭代整个映射来查找匹配项,但可以使用单个get(id)
但是,当您必须遍历映射并需要值时,可以遍历条目集而不是键集
public void doSomething(MyObj id){
// see https://stackoverflow.com/q/322715/2711488
List<Map<String, List<String>>> mapsList = new ArrayList<>();
for(Map.Entry<MyObj, Map<String, List<String>>> e: conMap.entrySet()){
if(e.getKey().key1.equals(id.key1)){
mapsList.add(e.getValue());
}
}
for(Map<String, List<String>> map: mapsList){
synchronized(map) {
//...
}
}
}
public void doSomething(MyObj id){
//看https://stackoverflow.com/q/322715/2711488
List mapsList=新建ArrayList();
对于(Map.Entry e:conMap.entrySet()){
如果(例如getKey().key1.equals(id.key1)){
add(e.getValue());
}
}
用于(地图:地图列表){
同步(地图){
//...
}
}
}
我认为你是对的。但是你为什么不调试并证明呢?我不能调试-它是随机发生的,多线程的,并且输入只在客户端可用。如果你不能调试,那么你可能想在向映射列表添加项之前尝试添加空检查。如果这是可行的,那就证明你的假设是正确的。否则,请查找可能修改conMap
的任何代码。
mapsList.add(conMap.get(objId));
public void doSomething(MyObj id){
// see https://stackoverflow.com/q/322715/2711488
List<Map<String, List<String>>> mapsList = new ArrayList<>();
for(Map.Entry<MyObj, Map<String, List<String>>> e: conMap.entrySet()){
if(e.getKey().key1.equals(id.key1)){
mapsList.add(e.getValue());
}
}
for(Map<String, List<String>> map: mapsList){
synchronized(map) {
//...
}
}
}