[BAEL-9044] - Moved articles out of core-java
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
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;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class CustomRecursiveAction extends RecursiveAction {
|
||||
|
||||
private String workLoad = "";
|
||||
private static final int THRESHOLD = 4;
|
||||
|
||||
private static Logger logger = Logger.getAnonymousLogger();
|
||||
|
||||
public CustomRecursiveAction(String workLoad) {
|
||||
this.workLoad = workLoad;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
|
||||
if (workLoad.length() > THRESHOLD) {
|
||||
ForkJoinTask.invokeAll(createSubtasks());
|
||||
} else {
|
||||
processing(workLoad);
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<CustomRecursiveAction> createSubtasks() {
|
||||
|
||||
List<CustomRecursiveAction> 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) {
|
||||
String result = work.toUpperCase();
|
||||
logger.info("This result - (" + result + ") - was processed by " + Thread.currentThread()
|
||||
.getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
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<Integer> {
|
||||
|
||||
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<CustomRecursiveTask> createSubtasks() {
|
||||
List<CustomRecursiveTask> 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.forkjoin.util;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
public class PoolUtil {
|
||||
|
||||
public static ForkJoinPool forkJoinPool = new ForkJoinPool(2);
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.threadlocalrandom;
|
||||
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
public class ThreadLocalRandomBenchMarkRunner {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Options options = new OptionsBuilder().include(ThreadLocalRandomBenchMarker.class.getSimpleName())
|
||||
.threads(1)
|
||||
.forks(1)
|
||||
.shouldFailOnError(true)
|
||||
.shouldDoGC(true)
|
||||
.jvmArgs("-server")
|
||||
.build();
|
||||
|
||||
new Runner(options).run();
|
||||
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.baeldung.threadlocalrandom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Warmup(iterations = 1)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
public class ThreadLocalRandomBenchMarker {
|
||||
|
||||
List<Callable<Integer>> randomCallables = new ArrayList<>();
|
||||
List<Callable<Integer>> threadLocalRandomCallables = new ArrayList<>();
|
||||
|
||||
@Setup(Level.Iteration)
|
||||
public void init() {
|
||||
Random random = new Random();
|
||||
randomCallables = new ArrayList<>();
|
||||
threadLocalRandomCallables = new ArrayList<>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
randomCallables.add(() -> {
|
||||
return random.nextInt();
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
threadLocalRandomCallables.add(() -> {
|
||||
return ThreadLocalRandom.current()
|
||||
.nextInt();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void randomValuesUsingRandom() throws InterruptedException {
|
||||
ExecutorService executor = Executors.newWorkStealingPool();
|
||||
executor.invokeAll(randomCallables);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void randomValuesUsingThreadLocalRandom() throws InterruptedException {
|
||||
ExecutorService executor = Executors.newWorkStealingPool();
|
||||
executor.invokeAll(threadLocalRandomCallables);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package com.baeldung.java8;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.forkjoin.CustomRecursiveAction;
|
||||
import com.baeldung.forkjoin.CustomRecursiveTask;
|
||||
import com.baeldung.forkjoin.util.PoolUtil;
|
||||
|
||||
public class Java8ForkJoinIntegrationTest {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.baeldung.thread.join;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Demonstrates Thread.join behavior.
|
||||
*
|
||||
*/
|
||||
public class ThreadJoinUnitTest {
|
||||
|
||||
final static Logger LOGGER = Logger.getLogger(ThreadJoinUnitTest.class.getName());
|
||||
|
||||
class SampleThread extends Thread {
|
||||
public int processingCount = 0;
|
||||
|
||||
SampleThread(int processingCount) {
|
||||
this.processingCount = processingCount;
|
||||
LOGGER.info("Thread " + this.getName() + " created");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LOGGER.info("Thread " + this.getName() + " started");
|
||||
while (processingCount > 0) {
|
||||
try {
|
||||
Thread.sleep(1000); // Simulate some work being done by thread
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.info("Thread " + this.getName() + " interrupted.");
|
||||
}
|
||||
processingCount--;
|
||||
LOGGER.info("Inside Thread " + this.getName() + ", processingCount = " + processingCount);
|
||||
}
|
||||
LOGGER.info("Thread " + this.getName() + " exiting");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNewThread_whenJoinCalled_returnsImmediately() throws InterruptedException {
|
||||
Thread t1 = new SampleThread(0);
|
||||
LOGGER.info("Invoking join.");
|
||||
t1.join();
|
||||
LOGGER.info("Returned from join");
|
||||
LOGGER.info("Thread state is" + t1.getState());
|
||||
assertFalse(t1.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStartedThread_whenJoinCalled_waitsTillCompletion()
|
||||
throws InterruptedException {
|
||||
Thread t2 = new SampleThread(1);
|
||||
t2.start();
|
||||
LOGGER.info("Invoking join.");
|
||||
t2.join();
|
||||
LOGGER.info("Returned from join");
|
||||
assertFalse(t2.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout()
|
||||
throws InterruptedException {
|
||||
Thread t3 = new SampleThread(10);
|
||||
t3.start();
|
||||
t3.join(1000);
|
||||
assertTrue(t3.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void givenThreadTerminated_checkForEffect_notGuaranteed()
|
||||
throws InterruptedException {
|
||||
SampleThread t4 = new SampleThread(10);
|
||||
t4.start();
|
||||
//not guaranteed to stop even if t4 finishes.
|
||||
do {
|
||||
|
||||
} while (t4.processingCount > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJoinWithTerminatedThread_checkForEffect_guaranteed()
|
||||
throws InterruptedException {
|
||||
SampleThread t4 = new SampleThread(10);
|
||||
t4.start();
|
||||
do {
|
||||
t4.join(100);
|
||||
} while (t4.processingCount > 0);
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.threadlocalrandom;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ThreadLocalRandomIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenUsingThreadLocalRandom_whenGeneratingRandomIntBounded_thenCorrect() {
|
||||
int leftLimit = 1;
|
||||
int rightLimit = 100;
|
||||
int generatedInt = ThreadLocalRandom.current().nextInt(leftLimit, rightLimit);
|
||||
|
||||
assertTrue(generatedInt < rightLimit && generatedInt >= leftLimit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingThreadLocalRandom_whenGeneratingRandomIntUnbounded_thenCorrect() {
|
||||
int generatedInt = ThreadLocalRandom.current().nextInt();
|
||||
|
||||
assertTrue(generatedInt < Integer.MAX_VALUE && generatedInt >= Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingThreadLocalRandom_whenGeneratingRandomLongBounded_thenCorrect() {
|
||||
long leftLimit = 1L;
|
||||
long rightLimit = 100L;
|
||||
long generatedLong = ThreadLocalRandom.current().nextLong(leftLimit, rightLimit);
|
||||
|
||||
assertTrue(generatedLong < rightLimit && generatedLong >= leftLimit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingThreadLocalRandom_whenGeneratingRandomLongUnbounded_thenCorrect() {
|
||||
long generatedInt = ThreadLocalRandom.current().nextLong();
|
||||
|
||||
assertTrue(generatedInt < Long.MAX_VALUE && generatedInt >= Long.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingThreadLocalRandom_whenGeneratingRandomDoubleBounded_thenCorrect() {
|
||||
double leftLimit = 1D;
|
||||
double rightLimit = 100D;
|
||||
double generatedInt = ThreadLocalRandom.current().nextDouble(leftLimit, rightLimit);
|
||||
|
||||
assertTrue(generatedInt < rightLimit && generatedInt >= leftLimit);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingThreadLocalRandom_whenGeneratingRandomDoubleUnbounded_thenCorrect() {
|
||||
double generatedInt = ThreadLocalRandom.current().nextDouble();
|
||||
|
||||
assertTrue(generatedInt < Double.MAX_VALUE && generatedInt >= Double.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void givenUsingThreadLocalRandom_whenSettingSeed_thenThrowUnsupportedOperationException() {
|
||||
ThreadLocalRandom.current().setSeed(0l);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user