来自池的CompletableFuture重用线程 [英] CompletableFuture reuse thread from pool
问题描述
我正在测试可实现的未来。
如此处所述
我以为线程将从公共池中重用,但是此摘要显示了奇怪的行为
I'm testing Completable Future. As described here I thought thread would be reused from common pool but this snippet shows strange behaviour
for (int i = 0; i < 10000; i++) {
final int counter = i;
CompletableFuture.supplyAsync(() -> {
System.out.println("Looking up " + counter + " on thread " + Thread.currentThread().getName());
return null;
});
}
我有这样的输出:
Looking up 0 on thread Thread-2
Looking up 1 on thread Thread-3
Looking up 2 on thread Thread-4
...
Looking up 10000 on thread Thread-10002
线程中查找10000为每个任务创建线程。
为什么我的所有completableFuture都不会重用公共池中的线程?
it looks like a new thread is created for each task. Why all of my completableFuture do not reuse thread from common pool?
MoreOver我已经用RxJava测试过了,并且可以在以下代码中正常工作:
MoreOver I've tested with RxJava and it works as excpected with this code:
for (int i = 0; i < 10000; i++) {
rxJobExecute(i).subscribeOn(Schedulers.io()).subscribe();
}
private Observable<String> rxJobExecute(int i) {
return Observable.fromCallable(() -> {
System.out.println("emission " + i + " on thread " + Thread.currentThread().getName());
return "tata";
});
}
输出
emission 8212 on thread RxIoScheduler-120
emission 8214 on thread RxIoScheduler-120
emission 8216 on thread RxIoScheduler-120
emission 8218 on thread RxIoScheduler-120
emission 8220 on thread RxIoScheduler-120
emission 7983 on thread RxIoScheduler-275
emission 1954 on thread RxIoScheduler-261
emission 1833 on thread RxIoScheduler-449
emission 1890 on thread RxIoScheduler-227
推荐答案
由于您只有2个处理器,则在应用程序启动时,值 Runtime.getRuntime()。availableProcessors()
仅观察到 1
处理器(
Chances are that since you only have 2 processors then the value Runtime.getRuntime().availableProcessors()
on starting of the application only observed 1
processor (the avialableProcessors will return any number between 1 and the number of processors on your machine and isn't quite deterministic).
ForkJoin公共池将每线程使用一个线程,而avialableProcessors将返回介于1和计算机上处理器数量之间的任意数字,并且不确定性)。任务线程池(如果并行度为1)。
The ForkJoin common pool will use a thread-per-task thread pool if the parallelism is 1.
要强制系统以特定的并行度加载(至少为此),请定义系统属性 -Djava.util.concurrent.ForkJoinPool.common.parallelism = 2
作为运行时参数
To force the system to load with a particular parallelism (for this at least) define the system property -Djava.util.concurrent.ForkJoinPool.common.parallelism=2
as a runtime argument
编辑:
我再次查看了内部逻辑。由于您有 2
个内核,因此并行性始终是使用每个任务线程。该逻辑期望大于或等于3,因此您需要将并行度更新为3
I looked again at the internal logic. Since you have 2
cores, the parallelism will always be to use thread-per-task. The logic expects greater than or equal to 3, so you will need to update parallelism to 3
-Djava.util.concurrent.ForkJoinPool.common .parallelism = 3
。
另一种方法是定义自己的ThreadPool
The alternative is to define your own ThreadPool
这篇关于来自池的CompletableFuture重用线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!