问题
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