2014-09-13 48 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

一个完整的堆栈跟踪,指向其中提到的行,将非常感激(并防止即将关闭你的问题)。 – 2014-09-13 14:08:51

+0

当请求异常帮助时,请引用异常的完整文本,并告诉我们代码块中的哪一行是异常引用的行。 – 2014-09-13 14:08:57

回答

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

您首先进行越界检查currentPtr,然后锁定,然后使用currentPtr作为数组索引。由于您在三个线程中重复使用相同的Runnable实例,因此currentPtr可能在此期间已被修改,从而导致超出边界索引。

相关问题