CompletableFuture reuse thread from pool

淺唱寂寞╮ 提交于 2019-12-12 17:53:50

问题


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;
            });
}

I have that kind of output:

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

it looks like a new thread is created for each task. Why all of my completableFuture do not reuse thread from common pool?

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";

        });
    }

output

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:


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).

The ForkJoin common pool will use a thread-per-task thread pool if the parallelism is 1.

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

Edit:

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.

The alternative is to define your own ThreadPool



来源:https://stackoverflow.com/questions/39165655/completablefuture-reuse-thread-from-pool

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!