2012-03-29 3 views
0

JUnit을 사용하여 동시성을 테스트하는 것이 이상적이지는 않지만 지금은 선택의 여지가없는 게시물을 읽었습니다. 설명 할 수없는 예외가 발생했습니다.JUnit 및 동시성 : 설명 할 수없는 오류

내가 요약, 테스트 실행

  • 내가 집행 인
  • 각 실행 가능한 1000 개보다 Runnable를 제출는
  • 내가 실행 프로그램 종료
  • JUnit을 대기리스트에 요소를 추가합니다 목록에 999 개의 요소 만 있음
  • 실행 가능한 catch 블록에 예외가 표시되지 않음

어떻게 동작합니까?

참고 : 수시로 예외가 발생합니다. 이 코드에는 관련이없는 부분이 있지만 뭔가 놓친 경우를 대비하여 거기에 남겨 두었습니다. XXXQuery은 enum입니다. 당신은 주위 동기화없이 여러 스레드에서 Runnable.run() 방법에 resultsArrayList에 추가 할 수 없습니다

public void testConcurrent() throws InterruptedException { 
    final int N_THREADS = 1000; 
    final XXXData xxxData = new AbstractXXXDataImpl(); 
    final List<QueryResult> results = new ArrayList<>(); 
    ExecutorService executor = Executors.newFixedThreadPool(N_THREADS); 
    for (int i = 0; i < N_THREADS; i++) { 
     final int j = i; 
     executor.submit(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        results.add(xxxData.get(XXXQuery.values()[j % XXXQuery.values().length])); 
       } catch (Exception e) { 
        System.out.println(e); 
       } 
      } 
     }); 
    } 
    executor.shutdown(); 
    executor.awaitTermination(10, TimeUnit.SECONDS); 
    assertEquals(N_THREADS, results.size()); 
} 
+0

어쩌면 어떤 상황에서 10 초가 1000 스레드가 완료되기에 충분하지 않을 수 있습니까? – mcfinnigan

+0

앞으로 예외를 제공하고 어떤 라인이 영향을 미치는지 보여주십시오. 감사. – Gray

+0

@mcfinnigan 테스트가 1 초 이내에 완료됩니다. – assylias

답변

2

.

어설 션이 실패한 메시지는 에 대한 N_THREADS의 호출이 있었지만 동시 처리 경쟁 조건 때문에 ArrayList이 더 적은 수의 항목을 보유하고 있음을 보여줍니다.

목록 대신 최종 배열을 사용합니다. 뭔가 같이 : 또한

final QueryResult[] results = new QueryResult[N_THREADS]; 
for (int i = 0; i < N_THREADS; i++) { 
    ... 
     public void run() { 
      results[j] = data.get(Query.values()[j % Query.values().length]); 
     } 

, 나는 꽤 XXXQuery.values()하지 않지만이 변경되지 않는 한 나는 루프 위의 변수에 그 당겨 것입니다.

관련 문제