gpt4 book ai didi

java - 在多线程程序中使用迭代器时出现并发修改异常

转载 作者:行者123 更新时间:2023-12-01 20:53:09 24 4
gpt4 key购买 nike

我的代码是:

class Processor implements Runnable {

private int id;
private Integer interaction;
private Set<Integer> subset;
private volatile static AtomicBoolean notRemoved = new AtomicBoolean(true);

public Object<E> dcp;
public Iterator<Integer> iterator;



public Processor(int id, Integer interaction, Set<Integer> subset, Object<E> dcp, Iterator<Integer> iterator) {
this.id = id;
this.interaction = interaction;
this.subset= subset;
this.dcp = dcp;
this.iterator = iterator;
}

public void run() {
while (Processor.notRemoved.get()){
System.out.println("Starting: " + this.subset);
if (this.dcp.PA.contains(this.interaction)){
this.subset.add(this.interaction);
this.dcp.increaseScore(this.subset);
if (!this.subset.contains(this.interaction) && Processor.notRemoved.get()){
Processor.notRemoved.set(false);
iterator.remove();
}
}

System.out.println("Completed: " + this.id);
}
}
}


public class ConcurrentApp {

public void multiThreadProgram (Object<E> dcp, int threads) {

ExecutorService executor = Executors.newFixedThreadPool(threads);

int i =1;
while ((dcp.PA.size() > i) && (i <= dcp.R)){
for (Iterator<Integer> iterator = dcp.PA.iterator(); iterator.hasNext();){
Integer interaction = iterator.next();
ArrayList<Integer> removed = new ArrayList<Integer>(dcp.PA);
removed.remove(interaction);
ArrayList<Set<Integer>> subsets = dcp.getSubsets(removed, i);
for (int j = 0; j< subsets.size(); j++){
try {
executor.submit(new Processor(j, interaction, subsets.get(j), dcp, iterator));
} catch (RejectedExecutionException e){
System.out.println("Task was rejected");
}
}
}
System.out.println("All tasks completed");
i++;
}
executor.shutdown();
System.out.println("All tasks submitted");
try {
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

我在 java.util.ArrayList$Itr.checkForComodification(未知来源) 和 java.util.ArrayList$Itr.next(未知来源) 处收到 java.util.ConcurrentModificationException... 。

但是,我认为通过使用迭代器,我可以避免在修改集合的同时迭代集合的问题。我在程序的非多线程实现中没有遇到这个问题,所以我假设这与多个线程使用迭代器执行某些操作有关。有人有什么想法吗?

最佳答案

无论您是否使用迭代器,Java 的 ArrayList 都不是线程安全的。

来自Javadoc :

If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.

...

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException

看看这个 question有关线程安全替代方案的讨论。基本上,您需要使用锁(例如同步块(synchronized block))或合适的线程安全列表。

关于java - 在多线程程序中使用迭代器时出现并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42844994/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com