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();
}
}
CodePudding user response:
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);