Stream.parallel() Uses Virtual Threads?

Alan Bateman Alan.Bateman at oracle.com
Sat May 11 05:16:22 UTC 2024


On 10/05/2024 18:36, Nathan Reynolds wrote:
> Does/will Stream.parallel() use virtual threads or stay with the Fork 
> Join common pool threads?
>
> Let's say I have a Stream where the "loop" is I/O bound. Here is an 
> example.
>
> list.
>    stream().
>    parallel().
>    map(MyClass::ioBoundOperation).
>    ...
>
> In Java 8, 11, and other pre-Java 21 versions, parallel() would use 
> the Fork Join common pool to execute ioBoundOperation() in multiple 
> threads.  If the list has many elements, then the Fork Join common 
> pool will run out of threads since there are roughly N threads where N 
> = the number of vCPUs.  Other parallel streams will then have to 
> wait.  I hope I captured the situation correctly.
>
> If parallel() uses virtual threads, then multiple parallel streams can 
> execute and they won't block each other since the number of virtual 
> threads can be very large.
>
> Let's say parallel() uses virtual threads, would it make sense to 
> always use parallel()?  I guess there is some small overhead for 
> creating a virtual thread.  So, processing a small list with short 
> CPU-bound operations may take more time than it saves.
>
We aren't planning to change parallel to use virtual threads, I don't 
think it would make sense in general.

Have you looked at Gatherers for doing intermediate operations yet? One 
of the built-ins is mapConcurrent [1] so in your example you could 
replace parallel().map(MyClass:ioBoundOperation) with 
mapConcurrent(MyClass:ioBoundOperation) and have the mapping function 
for each element run in its own virtual thread.

-Alan

[1] 
https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/util/stream/Gatherers.html#mapConcurrent(int,java.util.function.Function)


More information about the loom-dev mailing list