[JAVA] About the number of threads of Completable Future

Introduction

CompletableFuture When I checked the number of threads, it seems that there is an upper limit on the number of threads that can be set if I do not set it, so I searched for the setting and exceeded the upper limit.

Let's process the list of Completable Future for the time being

For the time being, let's make a list and process it without thinking about anything. It closes my eyes that what I'm doing is salty.

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        List<CompletableFuture<String>> list = new ArrayList<>();
        for(int i = 0; i < 100; i++) {
            list.add(CompletableFuture.supplyAsync(() -> {
                try {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                } catch (InterruptedException e) {

                }
                return "a";
            }));
        }
        
        CompletableFuture<Void> cf = CompletableFuture.allOf(
                list.toArray(new CompletableFuture[list.size()]));
        
        cf.whenComplete((ret, ex) -> {
            System.out.println(ret);
            System.out.println(ex);
          });

        Thread.sleep(20000);
        System.out.println("end");
    }
}

As you can see by running this, only 3 threads (4 core PC) are started. This doesn't work as I expected to start something like 100 in the code.

ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-1
ForkJoinPool.commonPool-worker-2
null
null
end

Try increasing the number of threads

Therefore, increase the number of threads that can be started. supplyAsync can take ʻExecutor as an argument, and it is possible to make various settings with java.util.concurrent.Executors`.

First of all, let's move it so that you can create as many tasks as you want with ʻExecutors.newFixedThreadPool (100)`.

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool = Executors.newFixedThreadPool(100);
        
        List<CompletableFuture<String>> list = new ArrayList<>();
        for(int i = 0; i < 100; i++) {
            list.add(CompletableFuture.supplyAsync(() -> {
                try {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(10000);
                } catch (InterruptedException e) {

                }
                return "a";
            }, pool));
        }
        
        CompletableFuture<Void> cf = CompletableFuture.allOf(
                list.toArray(new CompletableFuture[list.size()]));
        
        cf.whenComplete((ret, ex) -> {
            System.out.println(ret);
            System.out.println(ex);
          });

        Thread.sleep(20000);
        System.out.println("end");
    }
}

If you do this, you will see that 100 threads are running.

pool-1-thread-1
pool-1-thread-4
pool-1-thread-3
pool-1-thread-2
pool-1-thread-6
pool-1-thread-5
pool-1-thread-7
pool-1-thread-10
pool-1-thread-11
pool-1-thread-12
pool-1-thread-13
pool-1-thread-15
pool-1-thread-14
pool-1-thread-9
pool-1-thread-16
pool-1-thread-17
pool-1-thread-18
pool-1-thread-20
pool-1-thread-19
pool-1-thread-8
pool-1-thread-22
pool-1-thread-23
pool-1-thread-25
pool-1-thread-21
pool-1-thread-24
pool-1-thread-26
pool-1-thread-27
pool-1-thread-29
pool-1-thread-28
pool-1-thread-30
pool-1-thread-31
pool-1-thread-32
pool-1-thread-34
pool-1-thread-33
pool-1-thread-36
pool-1-thread-37
pool-1-thread-35
pool-1-thread-38
pool-1-thread-40
pool-1-thread-39
pool-1-thread-41
pool-1-thread-42
pool-1-thread-43
pool-1-thread-64
pool-1-thread-60
pool-1-thread-57
pool-1-thread-62
pool-1-thread-59
pool-1-thread-58
pool-1-thread-65
pool-1-thread-71
pool-1-thread-63
pool-1-thread-69
pool-1-thread-70
pool-1-thread-61
pool-1-thread-52
pool-1-thread-53
pool-1-thread-51
pool-1-thread-50
pool-1-thread-49
pool-1-thread-47
pool-1-thread-45
pool-1-thread-46
pool-1-thread-44
pool-1-thread-54
pool-1-thread-55
pool-1-thread-56
pool-1-thread-68
pool-1-thread-66
pool-1-thread-48
pool-1-thread-72
pool-1-thread-73
pool-1-thread-75
pool-1-thread-76
pool-1-thread-74
pool-1-thread-77
pool-1-thread-78
pool-1-thread-80
pool-1-thread-79
pool-1-thread-82
pool-1-thread-81
pool-1-thread-67
pool-1-thread-83
pool-1-thread-84
pool-1-thread-85
pool-1-thread-86
pool-1-thread-87
pool-1-thread-89
pool-1-thread-88
pool-1-thread-90
pool-1-thread-91
pool-1-thread-92
pool-1-thread-94
pool-1-thread-93
pool-1-thread-95
pool-1-thread-96
pool-1-thread-98
pool-1-thread-97
pool-1-thread-99
pool-1-thread-100
null
null
end

About processing that can be made with other Executors

This time I just wanted to start 100 threads, so I specified it with newFixedThreadPool, but if you want to reuse it, you can use newCachedThreadPool (from the code above, you can easily see that it is being used. ) Actually, if you want to fix one thread, there is newSingleThreadExecutor, so it is possible to control the thread startup according to the purpose. The correct answer depends on the intended use, so it seems necessary to get a clue while using it.

However, you can also create an Executor that delays with newScheduledThreadPool in Executors, but if you set this, it will be treated as 0 seconds delay, so it does not seem to make much sense. As far as the movement is seen, it feels like the movement is similar to newCachedThreadPool. Maybe I can delay it well, but I'm not sure.

Recommended Posts

About the number of threads of Completable Future
About the handling of Null
About the description of Docker-compose.yml
Limit the number of threads using Java's Executor Service
[Ruby] Questions and verification about the number of method arguments
Command to check the number and status of Java threads
About the behavior of ruby Hash # ==
About the basics of Android development
About the role of the initialize method
Think about the 7 rules of Optional
Summary about the introduction of Device
About the log level of java.util.logging.Logger
About the version of Docker's Node.js image
What is testing? ・ About the importance of testing
About the operation of next () and nextLine ()
About the initial display of Spring Framework
About the error message Invalid redeclaration of'***'
About the mechanism of the Web and HTTP
[Java] Check the number of occurrences of characters
Check the operation of the interface through threads
Think about the combination of Servlet and Ajax
About the description order of Java system properties
About the method
About Java threads
About the package
I checked the number of taxis with Ruby
Count the number of occurrences of a string in Ruby
[Swift] Get the number of steps with CMP edometer
[Grails] About the setting area and the setting items of application.yml
About the usefulness of monads from an object-oriented perspective
About the problem of deadlock in parallel processing in gem'sprockets' 4.0
Set the maximum number of characters in UITextField in RxSwift
Can the number of digits be Math.log10 (x) .floor + 1?
[Technical memo] About the advantages and disadvantages of Ruby
I learned about the existence of a gemspec file
Think about the JAVA = JAVAscript problem (needed in the future)
Output about the method # 2
About the StringBuilder class
The world of clara-rules (2)
Commentary: About the interface
About disconnect () of HttpURLConnection
About the asset pipeline
About the function double-java
About selection of OpenJDK
About DI of Spring ①
About the ternary operator
Judgment of the calendar
The world of clara-rules (4)
About DI of Spring ②
The world of clara-rules (3)
About the length method
About the Kernel module
About docker-compose PORT number
The world of clara-rules (5)
The idea of quicksort
About the authenticate method.
About the map method
About the ancestors method
About form. ○○ of form_with
[Output] About the database
Java 8 Completable Future Survey