Java HashMap中的ArrayIndexOutOfBoundsException
我有一个奇怪的例外,我无法复制(来自bugsense): 为什么Java HashMap中的ArrayIndexOutOfBoundsException,java,android,hashmap,Java,Android,Hashmap,我有一个奇怪的例外,我无法复制(来自bugsense): 为什么ConcurrentHashMap上的put方法可以抛出ArrayIndexOutOfBoundsException? (我也尝试使用ConcurrentHashMap,但没有任何运气) 有什么想法吗 编辑: 添加代码: final Map<String, DataSource> dataSources = new ConcurrentHashMap<String, DataSource>(); public
ConcurrentHashMap上的put方法可以抛出ArrayIndexOutOfBoundsException
?
(我也尝试使用ConcurrentHashMap,但没有任何运气)
有什么想法吗
编辑:
添加代码:
final Map<String, DataSource> dataSources = new ConcurrentHashMap<String, DataSource>();
public void setDataSource(@Nonnull String field, @Nullable DataSource source) {
// concurrent hash map doesnt allow null values
if (field != null) {
if (source != null) {
dataSources.put(field, source);
} else {
dataSources.remove(field);
}
}
}
final Map dataSources=new ConcurrentHashMap();
public void setDataSource(@Nonnull字符串字段,@Nullable数据源){
//并发哈希映射不允许空值
如果(字段!=null){
如果(源!=null){
dataSources.put(字段、源);
}否则{
数据源。删除(字段);
}
}
}
许多线程同时调用此方法
谢谢。堆栈跟踪显示您正在使用
我的诊断是,您设法获得了一个损坏的HashMap
对象。addNewEntry
方法正在索引主哈希数组(table
),但数组的长度(显然)为零。这是不应该发生的事情。。。而且(我认为)只有在扩展阵列时容量计算出错时才会发生这种情况。(检查代码如何处理空映射…)
可能(我猜)您在使用的Android版本的HashMap
实现中遇到了一个bug。但是,我认为更可能的情况是,损坏是由于应用程序使用多个线程使用/更新映射对象,而没有进行适当的同步。我建议你先探索这个理论;i、 检查你的同步
我不知道为什么更新的问题是关于ConcurrentHashMap
。stacktrace中的证据清楚地表明问题发生在HashMap
中。我只准备根据我能看到的实际证据提供诊断。相关代码是什么?有几个线程访问地图吗?如果是这样的话,可能会有一个潜在的问题,那就是当一个线程调整备份数组的大小时,另一个线程试图放入一个新条目。是的,那边有几个线程,但是我也尝试过使用ConcurrentHashMap
,但没有成功。读者请注意,stacktrace与OP后来添加的代码不匹配。这不是ConcurrentHashMap
中存在问题的证据。使用ConcurrentHashMap
进行同步映射是不够的?我原以为是这样。但老实说,在我做出判断之前,我希望看到一个SSCCE。您添加的代码显示了如何使用ConcurrentHashMap
。但是失败发生在您使用HashMap
时(您说您无法复制它!)。故障是否可再现?更新后的版本会发生这种情况吗?那东西的踪迹在哪里?你实际使用的是什么版本的Android?(你能提供一个链接到该类的确切版本的源代码吗?)
final Map<String, DataSource> dataSources = new ConcurrentHashMap<String, DataSource>();
public void setDataSource(@Nonnull String field, @Nullable DataSource source) {
// concurrent hash map doesnt allow null values
if (field != null) {
if (source != null) {
dataSources.put(field, source);
} else {
dataSources.remove(field);
}
}
}