来自池的CompletableFuture重用线程 [英] CompletableFuture reuse thread from pool

查看:116
本文介绍了来自池的CompletableFuture重用线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试可实现的未来。
此处所述
我以为线程将从公共池中重用,但是此摘要显示了奇怪的行为

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆