다음 코드 블록은 여러 스레드가 반복자를 통해 목록을 수정하고 있기 때문에 프로그램이 fail-fast 이벤트를 생성하고 ConcurrentModificationException
을 throw하는 기사에서 가져온 것입니다. 괜찮아. 뭐가 잘못 됐니?Failfast 이벤트 및 ConcurrentModificationException을 얻을 수없는 이유는 무엇입니까?
import java.util.*;
import java.util.concurrent.*;
public class FastFailTest {
private static List<String> list = new ArrayList<String>();
public static void main(String[] args) {
new ThreadOne().start();
new ThreadTwo().start();
}
private static void printAll() {
System.out.println("");
String value = null;
Iterator iter = list.iterator();
while(iter.hasNext()) {
value = (String)iter.next();
System.out.print(value+", ");
}
}
private static class ThreadOne extends Thread {
public void run() {
int i = 0;
while (i<6) {
list.add(String.valueOf(i));
printAll();
i++;
}
}
}
private static class ThreadTwo extends Thread {
public void run() {
int i = 10;
while (i<16) {
list.add(String.valueOf(i));
printAll();
i++;
}
}
}
}
스레드 OS가 실행 일정과 라이프 사이클을 관리하기 때문에 프로그래머가 자신의 실행 순서에 의존 할 수있는 몇 가지 루틴없는 동시 목록의 다음 클래스를 사용합니다. ThreadTwo가 OS에 의해 실행되기 전에 완전히 실행되는'ThreadOne'의 수명주기가 단축 될 수 있습니다. 따라서 동시성은 발생하지 않으며 예외도 발생하지 않습니다. 공유 리소스에 대한 동시 실행 및 수정의 가능성을 어느 정도 증가 시키려면 스레드에서 더 많은 시간이 걸리는 작업을 관리해야 할 수 있습니다. – STaefi
더 쉬운 방법은'for (String s : list) list.remove (s);'입니다. 사람들은'ConcurrentModificationException'을 (이름 때문에) 스레드와 연관시킵니다. 그러나 대부분의 경우 동시 프로그래밍으로 인한 것이 아닙니다. – Kayaman
예외가 발생합니다. 교훈은 다음과 같습니다. 멀티 스레딩 오류는 실험/테스트를 통해 실제로 발견하기가 어려울 수 있습니다. 올바른 다중 스레드 코드를 작성하는 가장 좋은 방법은 논리를 통해 매우 조심스럽게 생각하는 것입니다. 코드가 손상되었다는 가정에서 시작하여 그것이 아니라고 스스로 증명하십시오. – yshavit