Responsibility for thread management rests with ForkJoinPool. Client code should serve its tasks, and not mix stream processing. Note that tasks and threads are two different things; tasks are units of work performed, and threads are executed.
ForkJoinTask.compute () should convert fork () into smaller subtasks if the task is large enough to use the running parts of the task in parallel and simply process the task if the task is small enough to be run on a single thread. If the job is more than expected, it can fork () do some of the work and do the rest.
If ForkJoinTask.compute () translates into smaller subtasks, it can call join () before returning. ForkJoinPool will then either free the thread to work on other tasks, or create a temporary thread to work on other tasks to make full use of the available parallelism.
I consider it reasonable to assume that the corresponding number of worker threads remains busy as long as there are unfinished tasks, unless you explicitly block the thread in the compute () method.
The Sun tutorial provides more details on how to use these classes:
https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
source share