2014-09-13 2 views
0

출력 결과가 정확하지만 언젠가 IndexOutOFBound 예외가 발생합니다 ..... 컴파일러에서 재정렬 한 결과를 얻을 수 없습니까?왜 ArrayIndexOutOfBoundsException가 발생합니까?

package com.array.thread; 

import java.util.concurrent.*; 

public class EvenOddProcessor { 
    public static void main(String[] args) { 

     CyclicBarrier barrier = new CyclicBarrier(6, new Runnable() { 

      @Override 
      public void run() { 
       System.out.println("BARRIER BROKEN!!!"); 

      } 
     }); 

     int[] array = new int[10]; 
     for (int i = 0; i < array.length; i++) 
      array[i] = i; 

     ArrayIndexProcessor evenIndexProcessor = new ArrayIndexProcessor(array, 
       0, barrier); 
     ArrayIndexProcessor oddIndexProcessor = new ArrayIndexProcessor(array, 
       1, barrier); 

     Thread t1 = new Thread(evenIndexProcessor, "Even_1"); 
     Thread t2 = new Thread(evenIndexProcessor, "Even_2"); 
     Thread t3 = new Thread(evenIndexProcessor, "Even_3"); 
     t1.start(); 
     t2.start(); 
     t3.start(); 

     Thread t4 = new Thread(oddIndexProcessor, "Odd_1"); 
     Thread t5 = new Thread(oddIndexProcessor, "Odd_2"); 
     Thread t6 = new Thread(oddIndexProcessor, "Odd_3"); 
     t4.start(); 
     t5.start(); 
     t6.start(); 

     System.out.println(">>>>> Main thread is done"); 

    } 
} 

class ArrayIndexProcessor implements Runnable { 

    private final CyclicBarrier barrier; 

    private final int[] array; 

    private volatile int currentPtr = 0; 

    private Lock lock = new ReentrantLock(); 

    public ArrayIndexProcessor(int[] array, int startIndex, 
      CyclicBarrier barrier) { 
     this.array = array; 
     this.currentPtr = startIndex; 
     this.barrier = barrier; 
    } 

    public void run() { 
     try { 
      barrier.await(); 
     } catch (InterruptedException | BrokenBarrierException e) { 
      e.printStackTrace(); 
     } 
     while (!(array.length == 0) && (currentPtr < array.length)) { 
      lock.lock(); 
      try { 
       System.out.println(Thread.currentThread().getName() + "=" 
         + array[currentPtr]); 
       currentPtr = currentPtr + 2; 
      } finally { 
       lock.unlock(); 
      } 
     } 
    } 
} 
+0

여기에 언급 된 행에 대한 포인터가있는 전체 스택 추적은 많은 도움을받을 수 있으며 질문이 곧 마감되는 것을 막을 수 있습니다. –

+0

예외에 대한 도움을 요청할 때 예외의 전체 텍스트를 인용하고 예외가 참조하는 코드 블록의 행을 알려주십시오. –

답변

5
while (!(array.length == 0) && (currentPtr < array.length)) { 
     lock.lock(); 

먼저 다음, 다음 잠금, currentPtr에 경계-확인 배열 인덱스로 currentPtr를 사용합니다. 세 스레드에서 동일한 Runnable 인스턴스를 다시 사용 중이므로 currentPtr이 수정되어 범위를 벗어난 인덱스가 생성 될 수 있습니다.

관련 문제