1
list.parallelStream().forEach(element -> ...);

How can I limit the number of parallel threads nowadays?

There was a "hack" in the past to set a System property java.util.concurrent.ForkJoinPool.common.parallelism. But that feels wrong, plus it does not work anymore.

Could you advise how to chunk the list into 4 divisions, and then only run those 4 devisions in parallel?

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • 1
    “it does not work anymore”—really? Which Java version are you referring to? – Holger Feb 03 '22 at 13:48
  • Jdk14. Maybe I'm doing it wrong, but apart from, that I'd also don't want to change the parallelism throughout the application. But just throttle one specific stream. – membersound Feb 03 '22 at 13:49
  • 1
    Does it have to be a Stream operation? After all, you’re only using `forEach` in your example and literally asked “how to chunk the list into 4 divisions” which is actually a trivial operation. Unless you need a specific Stream feature. – Holger Feb 03 '22 at 14:35
  • @Holger ok that's true, but then the question still remains how to execute 4 divided lists in parallel... With or without streams. – membersound Feb 07 '22 at 08:54
  • 1
    `int a = 0, e = list.size(), c = e >>> 1, b = c >>> 1, d = e - b; executorService.invokeAll(Arrays.asList( Executors.callable(() -> list.subList(a, b) .forEach(action)), Executors.callable(() -> list.subList(b, c).forEach(action)), Executors.callable(() -> list.subList(c, d).forEach(action)), Executors.callable(() -> list.subList(d, e).forEach(action)) ));` – Holger Feb 07 '22 at 09:06

3 Answers3

1

I believe you rather need to limit the number of concurrent tasks being executed, therefore I don't find a necessity of using a parallel stream here as long as there is an easy solution located in the Java concurrent package. Use ExecutorService with a fixed thread pool of four instead.

Collection<Callable<Void>> = ...
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.invokeAll(callables);

If you really wish to use a custom thread pool within the parallel streams, please, refer to this question: Custom thread pool in Java 8 parallel stream.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
0

Use custom thread pool.

Read more here: https://www.baeldung.com/java-8-parallel-streams-custom-threadpool

and here: https://www.baeldung.com/java-when-to-use-parallel-stream

szeak
  • 325
  • 1
  • 7
0

You have to use custom ForkJoinPool with the number of needed threads to execute your task in parallel.

ForkJoinPool customThreadPool = new ForkJoinPool(NB_THREADS);
customThreadPool.submit(
() -> list.parallelStream().forEach(element -> ...);