java - java.util.concurrent.CopyOnWriteArrayList 中的 ConcurrentModificationException。(CopyOnWriteArrayList.java:141)
问题描述
第一:这段代码在多线程下有问题
@Override
public void onLoaded(List<Student> students) {
if(listener != null){
listener.onLoaded(students);
}
}
然后像这样改变
@Override
public void onLoaded(List<Student> students) {
CopyOnWriteArrayList<Student> copyList = new CopyOnWriteArrayList<Student>(students);
if(listener != null){
if(copyList.size() > 0){
listener.onLoaded(copyList);
}else{
listener.onLoaded(students);
}
}
}
这也有问题
Fatal Exception: java.util.ConcurrentModificationException
at java.util.ArrayList$SubList.size(ArrayList.java:1057)
at java.util.AbstractCollection.toArray(AbstractCollection.java:136)
at java.util.concurrent.CopyOnWriteArrayList.<init>(CopyOnWriteArrayList.java:141)
在 CopyOnWriteArrayList.java
/**
* Creates a new instance containing the elements of {@code collection}.
*/
@SuppressWarnings("unchecked")
public CopyOnWriteArrayList(Collection<? extends E> collection) {
this((E[]) collection.toArray());
}
AbstractCollection 实现 Collection,在 AbstractCollection 中
public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()];
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) // fewer elements than expected
return Arrays.copyOf(r, i);
r[i] = it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}
最后,就是问题所在。
我只知道我可以使用Lock来修复它,但我不知道它会导致Android中的ANR,我不能重复这个问题,我该如何修复它?
现在我正在尝试像这样修复它,可以吗?
@Override
public void onLoaded(List<Student> students) {
final CopyOnWriteArrayList<Student> copyList;
synchronized (students) {
copyList = new CopyOnWriteArrayList<Student>(students);
}
if(listener != null){
if(copyList.size() > 0){
listener.onLoaded(copyList);
}else{
listener.onLoaded(students);
}
}
}
解决方案
推荐阅读
- python - 模板不存在使用通用视图
- ios - Siri 快捷方式适用于 iPhone,但不适用于 HomePod
- php - 迁移表为空 - 无法运行 php artisan migrate
- laravel - 禁止从浏览器访问 Laravel API
- java - spring boot 2 属性配置
- java - Spring Boot REST:排序方向被忽略,但排序通常有效
- html - 在不同的标签中显示数组元素
- node.js - 如何运行写在另一个文件中的函数代码并在nodejs中顺序调用另一个文件
- c# - SqlHelper.ExecuteNonQuery 返回 -1
- javascript - Ionic 3,firebase 在相同键下的两个数据库中保存值