如何解决如何安全地从列表中删除元素
for (Iterator<Long> it = ids.iterator(); it.hasNext(); ) {
Long temp = it.next().longValue();
if (oo.contains(temp)) {
it.remove();
}
}
我做对了吗?
如果我在单线程和多线程环境中使用迭代器 remove()
,
我也不会收到任何 ConcurrentModificationException
或其他一些异常吗?
解决方法
如果我在单线程和多线程环境中都使用迭代器 remove()
,我是否也不会遇到任何 ConcurrentModificationException
或其他一些异常?
通常,对于单线程和多线程环境,您都会获得 ConcurrentModificationException
。
CME 可能由很多原因引起,而不仅仅是“在使用迭代器迭代列表时不使用 Iterator.remove
”。例如,下面是一些生成 CME 的代码:
List<String> list = new ArrayList<>(List.of("1","2"));
Iterator<String> iter = list.iterator();
iter.next();
list.add(0,"first!"); // adding to the list while iterating over it
iter.remove(); // we're using Iterator.remove here,still CME!
还有,
List<String> list = new ArrayList<>(List.of("1","2"));
// make two iterators of the same list
Iterator<String> iter1 = list.iterator();
Iterator<String> iter2 = list.iterator();
iter1.next(); // advance one of them
iter1.remove(); // we're using Iterator.remove here
iter2.next(); // iter2 doesn't know about iter1 has removed an element,so CME
问题中发生了类似的事情:Why does this Java code trigger a ConcurrentModificationException? 我已经回答了。
不过在你的代码中,我没有看到这样的事情发生,所以我认为在单线程中应该没问题。
但是,如果多个线程可以访问该列表,那么您就会遇到问题。 Iterator.remove
不应该为您解决所有的多线程同步问题。如果您没有进行适当的同步,另一个线程可以在您迭代列表时对列表进行任何结构更改。解决此问题的一种方法(根据您的用例肯定有更好的方法)是在对列表进行任何结构更改之前以及迭代之前获取锁。
标准库提供了一堆线程安全的集合。 Choose the appropriate one if you need.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。