来自池的CompletableFuture重用线程

时间:2016-08-26 11:51:52

标签: multithreading threadpool completable-future

我正在测试可完成的未来。 如上所述here 我认为线程可以从公共池中重用,但是这个片段显示了奇怪的行为

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

看起来像是为每个任务创建了一个新线程。 为什么我的所有completableFuture都不重用公共池中的线程?

MoreOver我已经使用RxJava进行了测试,它的效果与此代码一样:

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

1 个答案:

答案 0 :(得分:3)

由于您只有2个处理器,因此启动应用程序时的值Runtime.getRuntime().availableProcessors()只能观察到1个处理器(avialableProcessors将返回1到1之间的任何数字和机器上的处理器数量)并且不太确定。)

如果并行度为1,则ForkJoin公共池将使用每任务线程的线程池。

强制系统加载特定的并行性(至少为此)将系统属性-Djava.util.concurrent.ForkJoinPool.common.parallelism=2定义为运行时参数

编辑:

我再次看了内部逻辑。由于您拥有2个核心,因此并行性始终是使用每个任务的线程。逻辑期望大于或等于3,因此您需要将并行性更新为3

-Djava.util.concurrent.ForkJoinPool.common.parallelism=3

另一种方法是定义自己的ThreadPool