I found in this tutorial a way to iterate in parallel a collection of objects by setting threads priority, but this example uses the Burningwave Core library: is there a way to do the same with the standard Java API?
I found in this tutorial a way to iterate in parallel a collection of objects by setting threads priority, but this example uses the Burningwave Core library: is there a way to do the same with the standard Java API?
Here the code of the tutorial:
import static org.burningwave.core.assembler.StaticComponentContainer.IterableObjectHelper; import static org.burningwave.core.assembler.StaticComponentContainer.ManagedLoggerRepository; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.burningwave.core.iterable.IterableObjectHelper.IterationConfig; public class CollectionAndArrayIterator { public static void execute() { List<String> output = IterableObjectHelper.iterateAndGet( IterationConfig.of(buildCollection()) //Enabling parallel iteration when the input collection size is greater than 2 .parallelIf(inputColl -> inputColl.size() > 2) //Setting threads priority .withPriority(Thread.MAX_PRIORITY) //Setting up the output collection .withOutput(new ArrayList<String>()) .withAction((number, outputCollectionSupplier) -> { if (number > 500000) { //Terminating the current thread iteration early. IterableObjectHelper.terminateCurrentThreadIteration(); //If you need to terminate all threads iteration (useful for a find first iteration) use //IterableObjectHelper.terminateIteration(); } if ((number % 2) == 0) { outputCollectionSupplier.accept(outputCollection -> //Converting and adding item to output collection outputCollection.add(number.toString()) ); } }) ); IterableObjectHelper.iterate( IterationConfig.of(output) //Disabling parallel iteration .parallelIf(inputColl -> false) .withAction((number) -> { ManagedLoggerRepository.logInfo(CollectionAndArrayIterator.class::getName, "Iterated number: {}", number); }) ); ManagedLoggerRepository.logInfo( CollectionAndArrayIterator.class::getName, "Output collection size {}", output.size() ); } private static Collection<Integer> buildCollection() { Collection<Integer> inputCollection = new ArrayList<>(); for (int i = 1; i <= 1000000; i++) { inputCollection.add(i); } return inputCollection; } public static void main(String[] args) { execute(); } }
Advertisement
Answer
Referring to the answer from Custom thread pool in Java 8 parallel stream You can use List.parallelStream
with a Custom ForkJoinPool
. The trick is fill up the pool with a custom ForkJoinWorkerThreadFactory
that sets required priority to threads.
- Create a custom
ForkJoinWorkerThreadFactory
that sets the required thread priority. - Create a
ForkJoinPool
by passing this factory in constructor. - Submit the parallel stream task as explained in the above mentioned answer.
List<Integer> list = getList(); ForkJoinWorkerThreadFactory factory = pool -> { ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); worker.setPriority(5); return worker; }; ForkJoinPool pool = new ForkJoinPool(4, factory, null, true); int sum = pool.submit(() -> list.parallelStream().reduce(0, Integer::sum)).join(); System.out.println("sum: " + sum);