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