通过以下代码
ExecutorService executorService = Executors.newFixedThreadPool(3)
for (int i=0; i<10; i++){
executorService.execute(new Runnable() {
@Override
void run() {
try {
Thread.sleep(1*1000)
System.out.println("Thread " + Thread.currentThread().getName() + " processing item " + i)
} catch (InterruptedException e) {
e.printStackTrace()
}
}
})
}
我期待输出如下:
线程池-1-线程-2处理项目1
线程池-1-线程-3处理项目2
线程池-1-线程-2处理项目3
线程池-1-线程-3处理项目4
线程池-1-线程-2处理项目5
线程池-1-线程-2处理项目7
线程池-1-线程-3处理项目6
线程池-1-线程-2处理项目8
线程池-1-线程-3处理项目9
线程池-1-线程-1处理项目0
但事实证明是:
线程池-1-线程-1处理项目10
线程池-1-线程-1处理项目10
线程池-1-线程-1处理项目10
线程池-1-线程-1处理项目10
线程池-1-线程-1处理项目10
线程池-1-线程-1处理项目10
线程池-1-线程-1处理项目10
线程池-1-线程-1处理项目10
线程池-1-线程-2处理项目10
线程池-1-线程-3处理项目10
正确的输出是在executorService.exeute方法之前添加临时变量。这就是问题,是什么导致意外输出?
答案 0 :(得分:1)
你是什么意思“正确的输出是通过在executorService.exeute方法之前添加一个临时变量。”?
另外,你不应该期待那个输出。你无法保证这样的订单,例如我得到了:
Thread pool-1-thread-1 processing item 0
Thread pool-1-thread-2 processing item 1
Thread pool-1-thread-3 processing item 2
Thread pool-1-thread-3 processing item 5
Thread pool-1-thread-1 processing item 3
Thread pool-1-thread-2 processing item 4
Thread pool-1-thread-1 processing item 7
Thread pool-1-thread-2 processing item 8
Thread pool-1-thread-3 processing item 6
Thread pool-1-thread-1 processing item 9
使用此代码:
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int j = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1 * 1000);
System.out.println("Thread "
+ Thread.currentThread().getName()
+ " processing item " + j);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
答案 1 :(得分:0)
所有runnables共享i
的同一个实例。
当它们运行时,此变量的值为10
因此输出。
如果你使用一个闭包,每个runnable将获得一个i
的新实例,你将获得预期的输出:
ExecutorService executorService = Executors.newFixedThreadPool(3)
10.times { i ->
executorService.execute { ->
Thread.sleep(1000)
println "Thread ${Thread.currentThread().getName()} processing item $i"
}
}
executorService.shutdown()
但是他们不会按照你所说的顺序,因为线程......