我想出了以下代码来模拟实际情况。
并行运行100个任务,它们将完成的状态更新到主程序。 我使用CountDownLatch等待任务完成。
import java.util.concurrent.*;
import java.util.*;
public class Runner {
// Should be replaced with Collections.synchronizedList(new ArrayList())
public List completed = new ArrayList();
/**
* @param args
*/
public static void main(String[] args) {
Runner r = new Runner();
ExecutorService exe = Executors.newFixedThreadPool(30);
int tasks = 100;
CountDownLatch latch = new CountDownLatch(tasks);
for (int i = 0; i < tasks; i++) {
exe.submit(r.new Task(i, latch));
}
try {
latch.await();
System.out.println("Summary:");
System.out.println("Number of tasks completed: "
+ r.completed.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
exe.shutdown();
}
class Task implements Runnable {
private int id;
private CountDownLatch latch;
public Task(int id, CountDownLatch latch) {
this.id = id;
this.latch = latch;
}
public void run() {
Random r = new Random();
try {
Thread.sleep(r.nextInt(5000)); //Actual work of the task
} catch (InterruptedException e) {
e.printStackTrace();
}
completed.add(id);
latch.countDown();
}
}
}
当我运行该应用程序10次且至少运行3至4次时,该程序未打印正确数量的已完成任务。 理想情况下,它应该打印100(如果没有例外发生)。 但在某些情况下,它正在打印98、99等。
因此证明ArrayList的并发更新不会给出正确的结果。
如果我将ArrayList替换为Synchronized版本,则程序将输出正确的结果。