给我正确的输出,但有时得到IndexOutOFBound Exception .....无法获得编译器完成的重新排序?
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 :(得分:5)
while (!(array.length == 0) && (currentPtr < array.length)) {
lock.lock();
首先对currentPtr
进行边界检查,然后锁定,然后使用currentPtr
作为数组索引。由于您在三个线程中重用相同的Runnable
实例,因此在此期间可能已修改currentPtr
,从而导致越界索引。