2017-11-25 1 views
0

다음 코드 블록은 여러 스레드가 반복자를 통해 목록을 수정하고 있기 때문에 프로그램이 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++; 
     } 
    } 
} 

} 
+3

스레드 OS가 실행 일정과 라이프 사이클을 관리하기 때문에 프로그래머가 자신의 실행 순서에 의존 할 수있는 몇 가지 루틴없는 동시 목록의 다음 클래스를 사용합니다. ThreadTwo가 OS에 의해 실행되기 전에 완전히 실행되는'ThreadOne'의 수명주기가 단축 될 수 있습니다. 따라서 동시성은 발생하지 않으며 예외도 발생하지 않습니다. 공유 리소스에 대한 동시 실행 및 수정의 가능성을 어느 정도 증가 시키려면 스레드에서 더 많은 시간이 걸리는 작업을 관리해야 할 수 있습니다. – STaefi

+2

더 쉬운 방법은'for (String s : list) list.remove (s);'입니다. 사람들은'ConcurrentModificationException'을 (이름 때문에) 스레드와 연관시킵니다. 그러나 대부분의 경우 동시 프로그래밍으로 인한 것이 아닙니다. – Kayaman

+1

예외가 발생합니다. 교훈은 다음과 같습니다. 멀티 스레딩 오류는 실험/테스트를 통해 실제로 발견하기가 어려울 수 있습니다. 올바른 다중 스레드 코드를 작성하는 가장 좋은 방법은 논리를 통해 매우 조심스럽게 생각하는 것입니다. 코드가 손상되었다는 가정에서 시작하여 그것이 아니라고 스스로 증명하십시오. – yshavit

답변

1

코드를 실행하면 가끔 CME가 표시되는 경우가 있습니다.

다음은 예외가 발생했을 때 스택 추적 및 출력입니다. 글쎄, 한가지는 두 스레드가 모두 데이터를 삽입하려고 할 때 시간이 서로 충돌하지 않는다는 것입니다. 왜냐하면 두 스레드 모두 목록 채우기 시간이 매우 짧기 때문입니다. 코드를 실행했습니다. 예외가 있습니다.

ThreadOne은 [0,5]의 값만 삽입 할 수 있으므로 스레드 2는 [10,15] 값만 삽입 할 수 있습니다. 최종 출력 행은 [0, 10, 11, 12, 13, 14, 15, 스레드에서 예외 "스레드 0"java.util.ConcurrentModificationException]

내가 ThreadTwo 목록의 요소를 삽입 완료했다고 생각하지만, 하나는 아래 0

만 하나의 요소를 추가했다 스레드 스택 추적입니다 .

0, 0, 10, 10, 
0, 10, 11, 
0, 10, 11, 12, 
0, 10, 11, 12, 13, 
0, 10, 11, 12, 13, 14, 
0, 10, 11, 12, 13, 14, 15, Exception in thread "Thread-0" java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) 
    at java.util.ArrayList$Itr.next(ArrayList.java:851) 
    at com.failfast.FastFailTest.printAll(FastFailTest.java:23) 
    at com.failfast.FastFailTest.access$1(FastFailTest.java:17) 
    at com.failfast.FastFailTest$ThreadOne.run(FastFailTest.java:34)