Java execuetorService 运行 太快了?
Java execuetorService running too fast?
通过以下代码
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-thread-1处理项目0
但结果是:
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-线程2处理项目10
线程池-1-线程3处理项目10
正确的输出是在 executorService.exeute 方法之前添加一个临时变量。问题来了,出现意外输出的原因是什么?
- 首先你的代码不会编译(至少在 Java 中不会,可能会在 Groovy 中编译)
- 'i' 不能在块内使用,因为它不是最终的,也不能是最终的,因为它在 for 循环中使用。
"The correct out put is by adding a temp variable before the executorService.exeute method."是什么意思?
此外,您不应该期待该输出。你不能保证这样的顺序,例如我得到:
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();
}
}
});
}
}
您的所有 运行nables 共享 i
的同一个实例。
到他们 运行 时,此变量的值为 10
因此输出。
如果您使用闭包,每个 运行nable 将获得 i
的一个新实例,您将获得预期的输出:
ExecutorService executorService = Executors.newFixedThreadPool(3)
10.times { i ->
executorService.execute { ->
Thread.sleep(1000)
println "Thread ${Thread.currentThread().getName()} processing item $i"
}
}
executorService.shutdown()
但它们不会按照您预期的顺序排列,因为线程...
通过以下代码
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-thread-1处理项目0
但结果是:
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-thread-1处理项目10
线程池-1-线程2处理项目10
线程池-1-线程3处理项目10
正确的输出是在 executorService.exeute 方法之前添加一个临时变量。问题来了,出现意外输出的原因是什么?
- 首先你的代码不会编译(至少在 Java 中不会,可能会在 Groovy 中编译)
- 'i' 不能在块内使用,因为它不是最终的,也不能是最终的,因为它在 for 循环中使用。
"The correct out put is by adding a temp variable before the executorService.exeute method."是什么意思?
此外,您不应该期待该输出。你不能保证这样的顺序,例如我得到:
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();
}
}
});
}
}
您的所有 运行nables 共享 i
的同一个实例。
到他们 运行 时,此变量的值为 10
因此输出。
如果您使用闭包,每个 运行nable 将获得 i
的一个新实例,您将获得预期的输出:
ExecutorService executorService = Executors.newFixedThreadPool(3)
10.times { i ->
executorService.execute { ->
Thread.sleep(1000)
println "Thread ${Thread.currentThread().getName()} processing item $i"
}
}
executorService.shutdown()
但它们不会按照您预期的顺序排列,因为线程...