使用 ExecutorService 的并发
concurrency using ExecutorService
我有这个简单的程序,可以使用 ThreadPool 和 ExecutorService 计算从 1 到 9 的数字。
每个线程等待 1 秒执行。但是,下面的程序为我提供了每次执行的随机输出。
如何解决这个问题,让它始终产生 45?
public static void main(String[] args) throws InterruptedException {
AtomicLong count = new AtomicLong(0);
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
for(Integer i : list) {
executor.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count.set(count.get() + i);
}
});
}
System.out.println("Waiting...");
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
System.out.println("Total::"+count.get());
System.out.println("Done");
}
AtomicLong 有特殊的原子方法。您只有在使用它们时才能获得原子保证(分别调用 add()
和 get()
将 而不是 是原子的)。 AtomicLong 上有一些方法会以原子方式 "add" 到当前值。
而不是
count.set(count.get() + i);
使用
count.addAndGet(i);
方法addAndGet以原子方式添加值,但顺序get和set不是原子操作。
我有这个简单的程序,可以使用 ThreadPool 和 ExecutorService 计算从 1 到 9 的数字。 每个线程等待 1 秒执行。但是,下面的程序为我提供了每次执行的随机输出。
如何解决这个问题,让它始终产生 45?
public static void main(String[] args) throws InterruptedException {
AtomicLong count = new AtomicLong(0);
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
for(Integer i : list) {
executor.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count.set(count.get() + i);
}
});
}
System.out.println("Waiting...");
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
System.out.println("Total::"+count.get());
System.out.println("Done");
}
AtomicLong 有特殊的原子方法。您只有在使用它们时才能获得原子保证(分别调用 add()
和 get()
将 而不是 是原子的)。 AtomicLong 上有一些方法会以原子方式 "add" 到当前值。
而不是
count.set(count.get() + i);
使用
count.addAndGet(i);
方法addAndGet以原子方式添加值,但顺序get和set不是原子操作。