diff --git a/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java b/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java new file mode 100644 index 0000000000..84476f8c66 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java @@ -0,0 +1,46 @@ +package com.baeldung.forkjoin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.RecursiveAction; + +public class CustomRecursiveAction extends RecursiveAction { + + private String workLoad = ""; + + private static final int THRESHOLD = 4; + + public CustomRecursiveAction(String workLoad) { + this.workLoad = workLoad; + } + + @Override + protected void compute() { + + if(workLoad.length() > THRESHOLD) { + ForkJoinTask.invokeAll(createSubtasks()); + } else { + processing(workLoad); + } + } + + private Collection createSubtasks() { + + List subtasks = + new ArrayList<>(); + + String partOne = workLoad.substring(0, workLoad.length()/2); + String partTwo = workLoad.substring(workLoad.length()/2, workLoad.length()); + + subtasks.add(new CustomRecursiveAction(partOne)); + subtasks.add(new CustomRecursiveAction(partTwo)); + + return subtasks; + } + + private void processing(String work) { + work.toUpperCase(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java b/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java new file mode 100644 index 0000000000..c78dd51d27 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java @@ -0,0 +1,51 @@ +package com.baeldung.forkjoin; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.RecursiveTask; + +public class CustomRecursiveTask extends RecursiveTask { + + private int[] arr; + + private static final int THRESHOLD = 20; + + public CustomRecursiveTask(int[] arr) { + this.arr = arr; + } + + @Override + protected Integer compute() { + + if (arr.length > THRESHOLD) { + + return ForkJoinTask.invokeAll(createSubtasks()) + .stream() + .mapToInt(ForkJoinTask::join) + .sum(); + + } else { + return processing(arr); + } + } + + private Collection createSubtasks() { + List dividedTasks = new ArrayList<>(); + dividedTasks.add(new CustomRecursiveTask( + Arrays.copyOfRange(arr, 0, arr.length / 2))); + dividedTasks.add(new CustomRecursiveTask( + Arrays.copyOfRange(arr, arr.length / 2, arr.length))); + return dividedTasks; + } + + private Integer processing(int[] arr) { + return Arrays.stream(arr) + .filter(a -> a > 10 && a < 27) + .map(a -> a * 10) + .sum(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java b/core-java-8/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java new file mode 100644 index 0000000000..521616600f --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java @@ -0,0 +1,10 @@ +package com.baeldung.forkjoin.util; + + +import java.util.concurrent.ForkJoinPool; + +public class PoolUtil { + + public static ForkJoinPool forkJoinPool = new ForkJoinPool(2); + +} diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8ForkJoinTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8ForkJoinTest.java new file mode 100644 index 0000000000..d37c1c89d7 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/java8/Java8ForkJoinTest.java @@ -0,0 +1,101 @@ +package com.baeldung.java8; + + + +import com.baeldung.forkjoin.CustomRecursiveAction; +import com.baeldung.forkjoin.CustomRecursiveTask; +import com.baeldung.forkjoin.util.PoolUtil; +import org.junit.Before; +import org.junit.Test; + +import java.util.Random; +import java.util.concurrent.ForkJoinPool; + +import static org.junit.Assert.*; + +public class Java8ForkJoinTest { + + private int[] arr; + private CustomRecursiveTask customRecursiveTask; + + @Before + public void init() { + Random random = new Random(); + arr = new int[50]; + for (int i = 0; i < arr.length; i++) { + arr[i] = random.nextInt(35); + } + customRecursiveTask = new CustomRecursiveTask(arr); + } + + + @Test + public void callPoolUtil_whenExistsAndExpectedType_thenCorrect() { + + ForkJoinPool forkJoinPool = PoolUtil.forkJoinPool; + ForkJoinPool forkJoinPoolTwo = PoolUtil.forkJoinPool; + + assertNotNull(forkJoinPool); + assertEquals(2, forkJoinPool.getParallelism()); + assertEquals(forkJoinPool, forkJoinPoolTwo); + + } + + @Test + public void callCommonPool_whenExistsAndExpectedType_thenCorrect() { + + ForkJoinPool commonPool = ForkJoinPool.commonPool(); + ForkJoinPool commonPoolTwo = ForkJoinPool.commonPool(); + + assertNotNull(commonPool); + assertEquals(commonPool, commonPoolTwo); + + } + + @Test + public void executeRecursiveAction_whenExecuted_thenCorrect() { + + CustomRecursiveAction myRecursiveAction = new CustomRecursiveAction("ddddffffgggghhhh"); + ForkJoinPool.commonPool().invoke(myRecursiveAction); + + assertTrue(myRecursiveAction.isDone()); + + } + + @Test + public void executeRecursiveTask_whenExecuted_thenCorrect() { + + ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); + + forkJoinPool.execute(customRecursiveTask); + int result = customRecursiveTask.join(); + assertTrue(customRecursiveTask.isDone()); + + forkJoinPool.submit(customRecursiveTask); + int resultTwo = customRecursiveTask.join(); + assertTrue(customRecursiveTask.isDone()); + + } + + @Test + public void executeRecursiveTaskWithFJ_whenExecuted_thenCorrect() { + + CustomRecursiveTask customRecursiveTaskFirst = new CustomRecursiveTask(arr); + CustomRecursiveTask customRecursiveTaskSecond = new CustomRecursiveTask(arr); + CustomRecursiveTask customRecursiveTaskLast = new CustomRecursiveTask(arr); + + customRecursiveTaskFirst.fork(); + customRecursiveTaskSecond.fork(); + customRecursiveTaskLast.fork(); + int result = 0; + result += customRecursiveTaskLast.join(); + result += customRecursiveTaskSecond.join(); + result += customRecursiveTaskFirst.join(); + + assertTrue(customRecursiveTaskFirst.isDone()); + assertTrue(customRecursiveTaskSecond.isDone()); + assertTrue(customRecursiveTaskLast.isDone()); + assertTrue(result != 0); + + } +}