因此,在我为好玩而编写的各种程序中,我遇到了并发修改异常。
在我解决这个问题的天真尝试中,我使用了Atomic而不是某种并发集合。我有点熟悉为什么这是套管错误。本质上,ArrayList的各个元素是不同步的,可以由不同的线程随意修改。
有人能帮我总结一下吗
发布于 2016-06-25 13:55:35
我想你混淆了ConcurrentModification是什么意思.
最常见的情况是迭代一个集合并在循环中修改它。
例如,如果您执行以下操作
public static void main(String[] args) {
List<String> l = new LinkedList<>();
for(int i=0; i < 100; i++) {
l.add("banana"+i);
}
for (String s : l) {
if("banana10".equals(s)) {
l.remove(s);
}
}
}...this会给你一个ConcurrentModificationException。注意,我没有产生任何线程。
正确的方法如下:
public static void main(String[] args) {
List<String> l = new LinkedList<>();
for(int i=0; i < 100; i++) {
l.add("banana"+i);
}
for (Iterator<String> iterator = l.iterator(); iterator.hasNext();) {
String s = iterator.next();
if("banana10".equals(s)) {
iterator.remove();
}
}
}注意,在遍历集合时,使用迭代器来修改集合。
所以,我不认为你有并发问题!
如果希望使集合线程安全,则需要查看线程安全的语义。如果您希望允许多个线程访问同一个集合,那么ConcurrentList将是一种很好的方法。如果需要原子设置的列表引用,则可以使用原子引用。
发布于 2016-06-25 13:48:54
使用AtomicReference存储对象(如集合)不足以使其线程安全。实际上,如果您在AtomicReference中放置的对象不像ArrayList那样是线程安全的,那么如果我们有多个线程试图并发地修改其状态,那么使用它仍然是不安全的。因此,好的方法仍然是在AtomicReference中放入一个不可变的对象,这样它的状态就不能再被多个线程修改了。例如,在集合的情况下,可以对列表使用Collections.unmodifiable*类型的方法(如Collections.unmodifiableList(List) ),以便将集合的不变版本放入AtomicReference。
如果您需要线程安全集合,您应该查看包java.util.concurrent中的类,您将发现集合本身是线程安全的。例如,如果您大部分时间阅读并且很少修改您的List,则可以使用线程安全和高效的列表CopyOnWriteArrayList。
https://stackoverflow.com/questions/38028892
复制相似问题