我正在从多个线程修改同一列表,是否应该触发 迭代列表时出现ConcurrentModificationException?
如何触发此异常?
public class ConcurrentTest {
static List<String> list = setupList();
public static List<String> setupList() {
System.out.println("setup predefined list");
List<String> l = new ArrayList();
for(int i = 0; i < 50;i++) {
l.add("test" + i);
}
return l;
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(50);
for(int i = 0; i < 50; i++) {
executorService.submit( () -> {
list.add("key1");
Thread currentThread = Thread.currentThread();
System.out.println( Thread.currentThread().getName() + ", " + list.size() );
for(String val: list) {
try {
Thread.sleep(25);
}
catch(Exception e) {
}
}
});
}
executorService.shutdown();
}
}
答案 0 :(得分:1)
在对列表进行迭代时修改列表时,会触发ConcurrentModificationException。在您遍历列表的代码中,您仅使线程处于睡眠状态,而不修改线程。这将触发异常:
path
答案 1 :(得分:1)
您是否检查了下面的块是否抛出异常。
try {
list.add("key1");
Thread currentThread = Thread.currentThread();
System.out.println( Thread.currentThread().getName() + ", " + list.size() );
for(String val: list) {
try {
Thread.sleep(25);
}
catch(Exception e) {
}
}
}catch (Exception e) {
e.printStackTrace();
}
请环绕try ... catch块和print()错误消息以检查其是否抛出错误。
答案 2 :(得分:0)
您的代码确实(并且可以)产生ConcurrentModificationException
。您没有抓住它来打印它。
通过下面的内容,我们可以看到它确实抛出了许多ConcurrentModificationException
。
try {
for (String val : list) {
try {
Thread.sleep(25);
} catch (Exception e) {
}
}
} catch (Exception e) {
e.printStackTrace();
}
注意:在Javadoc中,
请注意,不能保证迭代器的快速失败行为 因为通常来说,不可能在 存在不同步的并发修改。快速迭代器 尽最大努力抛出{@code ConcurrentModificationException}。 因此,编写依赖于此的程序是错误的 正确性的例外:迭代器的快速失败行为 应该仅用于检测错误
另请参阅:java.util.ConcurrentModificationException not thrown when expected
或者,您可以获取返回的Future
并将它们收集在列表中。这样,在(至少)一种期货上调用get
时,您将获得异常。