El siguiente ejemplo ejecuta el rellenado de un array de bytes de un tamaño importante de dos maneras:
Muy interesante este concepto, a tener en cuenta para tareas grandes susceptibles de ser divididas en tareas más pequeñas.
Me recordó un poco al principio inicial de MapReduce (divide una tarea grande en tareas pequeñas.... y vencerás.
La salida, en el caso del que escribe, fue la siguiente:
Sequential processing time: 1683 ms
Sequential processing time: 1662 ms
Number of processor available: 2
Parallel processing time: 930 ms
Parallel processing time: 851 ms
Number of steals: 598
Saludos cordiales y gracias por su atención, como siempre un gusto
package com.sprunck.sample; import static java.util.Arrays.asList; import java.util.Random; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; public class ForkJoinRandomFillAction { Random random = new Random(); public void loadArray(int[] array) { for (int i = 0; i < array.length; i++) { array[i] = random.nextInt(10000); // Generates numbers from 0 to // 10000 } } public static void main(String[] args) { ForkJoinRandomFillAction sort = new ForkJoinRandomFillAction(); int arrayLength = 1_00_00_0000; int array[] = new int[arrayLength]; // No. of times sequential & Parallel operation should be performed to // warm up HotSpot JVM final int iterations = 2; for (int i = 0; i < iterations; i++) { long start = System.currentTimeMillis(); sort.loadArray(array); System.out.println("Sequential processing time: " + (System.currentTimeMillis() - start) + " ms"); } System.out.println("Number of processor available: " + Runtime.getRuntime().availableProcessors()); ForkJoinPool fjpool = new ForkJoinPool(64); // Default parallelism level // = // Runtime.getRuntime().availableProcessors() for (int i = 0; i < iterations; i++) { // Create a task with the complete array RecursiveAction task = new RandomFillAction(array, 0, array.length); long start = System.currentTimeMillis(); fjpool.invoke(task); System.out.println("Parallel processing time: " + (System.currentTimeMillis() - start) + " ms"); } System.out .println("Number of steals: " + fjpool.getStealCount() + "\n"); } } class RandomFillAction extends RecursiveAction { private static final long serialVersionUID = 1L; final int low; final int high; private int[] array; final int splitSize = 40000; // Some threshold size to spit the task public RandomFillAction(int[] array, int low, int high) { this.low = low; this.high = high; this.array = array; } @Override protected void compute() { if (high - low > splitSize) { // task is huge so divide in half int mid = (low + high) / 2; invokeAll(asList(new RandomFillAction(array, low, mid), new RandomFillAction(array, mid, high))); } else { // Some calculation logic Random random = new Random(); for (int i = low; i < high; i++) { array[i] = random.nextInt(10000); } } } }