[BAEL-6486] - Returning a Value After Finishing Thread's Job in Java (#14101)
* feat: threads with return value * pmd violation
This commit is contained in:
parent
9ff3b1dd9b
commit
f265b51841
@ -0,0 +1,29 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.task;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class FactorialCalculator {
|
||||||
|
|
||||||
|
public static BigInteger factorial(BigInteger end) {
|
||||||
|
BigInteger start = BigInteger.ONE;
|
||||||
|
BigInteger res = BigInteger.ONE;
|
||||||
|
|
||||||
|
for (int i = start.add(BigInteger.ONE)
|
||||||
|
.intValue(); i <= end.intValue(); i++) {
|
||||||
|
res = res.multiply(BigInteger.valueOf(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BigInteger factorial(BigInteger start, BigInteger end) {
|
||||||
|
BigInteger res = start;
|
||||||
|
|
||||||
|
for (int i = start.add(BigInteger.ONE)
|
||||||
|
.intValue(); i <= end.intValue(); i++) {
|
||||||
|
res = res.multiply(BigInteger.valueOf(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.task.callable;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class CallableExecutor {
|
||||||
|
|
||||||
|
public BigInteger execute(List<CallableFactorialTask> tasks) {
|
||||||
|
|
||||||
|
BigInteger result = BigInteger.ZERO;
|
||||||
|
|
||||||
|
ExecutorService cachedPool = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
|
List<Future<BigInteger>> futures;
|
||||||
|
|
||||||
|
try {
|
||||||
|
futures = cachedPool.invokeAll(tasks);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// exception handling example
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Future<BigInteger> future : futures) {
|
||||||
|
try {
|
||||||
|
result = result.add(future.get());
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
// exception handling example
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.task.callable;
|
||||||
|
|
||||||
|
import static com.baeldung.concurrent.threadreturnvalue.task.FactorialCalculator.factorial;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class CallableFactorialTask implements Callable<BigInteger> {
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
|
||||||
|
public CallableFactorialTask(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigInteger call() {
|
||||||
|
return factorial(BigInteger.valueOf(value));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.task.fork;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class ForkExecutor {
|
||||||
|
|
||||||
|
private final ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
|
||||||
|
|
||||||
|
public BigInteger execute(ForkFactorialTask forkFactorial) {
|
||||||
|
return forkJoinPool.invoke(forkFactorial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger execute(List<Callable<BigInteger>> forkFactorials) {
|
||||||
|
List<Future<BigInteger>> futures = forkJoinPool.invokeAll(forkFactorials);
|
||||||
|
|
||||||
|
BigInteger result = BigInteger.ZERO;
|
||||||
|
|
||||||
|
for (Future<BigInteger> future : futures) {
|
||||||
|
try {
|
||||||
|
result = result.add(future.get());
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
// exception handling example
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.task.fork;
|
||||||
|
|
||||||
|
import static com.baeldung.concurrent.threadreturnvalue.task.FactorialCalculator.factorial;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.concurrent.RecursiveTask;
|
||||||
|
|
||||||
|
public class ForkFactorialTask extends RecursiveTask<BigInteger> {
|
||||||
|
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
private final int threshold;
|
||||||
|
|
||||||
|
public ForkFactorialTask(int end, int threshold) {
|
||||||
|
this.start = 1;
|
||||||
|
this.end = end;
|
||||||
|
this.threshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForkFactorialTask(int start, int end, int threshold) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
this.threshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BigInteger compute() {
|
||||||
|
|
||||||
|
BigInteger sum = BigInteger.ONE;
|
||||||
|
|
||||||
|
if (end - start > threshold) {
|
||||||
|
|
||||||
|
int middle = (end + start) / 2;
|
||||||
|
|
||||||
|
return sum.multiply(new ForkFactorialTask(start, middle, threshold).fork()
|
||||||
|
.join()
|
||||||
|
.multiply(new ForkFactorialTask(middle + 1, end, threshold).fork()
|
||||||
|
.join()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum.multiply(factorial(BigInteger.valueOf(start), BigInteger.valueOf(end)));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.callable;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadreturnvalue.task.callable.CallableExecutor;
|
||||||
|
import com.baeldung.concurrent.threadreturnvalue.task.callable.CallableFactorialTask;
|
||||||
|
|
||||||
|
public class CallableUnitTest {
|
||||||
|
|
||||||
|
private final CallableExecutor callableExecutor = new CallableExecutor();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenCallableExecutor_whenExecuteFactorial_thenResultOk() {
|
||||||
|
BigInteger result = callableExecutor.execute(Arrays.asList(new CallableFactorialTask(5), new CallableFactorialTask(3)));
|
||||||
|
assertEquals(BigInteger.valueOf(126), result);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.completableFuture;
|
||||||
|
|
||||||
|
import static com.baeldung.concurrent.threadreturnvalue.task.FactorialCalculator.factorial;
|
||||||
|
import static java.util.concurrent.CompletableFuture.allOf;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class CompletableFutureUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenCompletableFuture_whenSupplyAsyncFactorial_thenResultOk() throws ExecutionException, InterruptedException {
|
||||||
|
CompletableFuture<BigInteger> completableFuture = CompletableFuture.supplyAsync(() -> factorial(BigInteger.valueOf(10)));
|
||||||
|
assertEquals(BigInteger.valueOf(3628800), completableFuture.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenCompletableFuture_whenComposeTasks_thenResultOk() throws ExecutionException, InterruptedException {
|
||||||
|
CompletableFuture<BigInteger> completableFuture = CompletableFuture.supplyAsync(() -> factorial(BigInteger.valueOf(3)))
|
||||||
|
.thenCompose(inputFromFirstTask -> CompletableFuture.supplyAsync(() -> factorial(inputFromFirstTask)));
|
||||||
|
assertEquals(BigInteger.valueOf(720), completableFuture.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenCompletableFuture_whenAllOfTasks_thenResultOk() {
|
||||||
|
CompletableFuture<BigInteger> asyncTask1 = CompletableFuture.supplyAsync(() -> BigInteger.valueOf(5));
|
||||||
|
CompletableFuture<String> asyncTask2 = CompletableFuture.supplyAsync(() -> "3");
|
||||||
|
|
||||||
|
BigInteger result = allOf(asyncTask1, asyncTask2).thenApplyAsync(fn -> factorial(asyncTask1.join()).add(factorial(new BigInteger(asyncTask2.join()))), Executors.newFixedThreadPool(1))
|
||||||
|
.join();
|
||||||
|
|
||||||
|
assertEquals(BigInteger.valueOf(126), result);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.concurrent.threadreturnvalue.fork;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadreturnvalue.task.callable.CallableFactorialTask;
|
||||||
|
import com.baeldung.concurrent.threadreturnvalue.task.fork.ForkExecutor;
|
||||||
|
import com.baeldung.concurrent.threadreturnvalue.task.fork.ForkFactorialTask;
|
||||||
|
|
||||||
|
public class ForkUnitTest {
|
||||||
|
|
||||||
|
private final ForkExecutor forkExecutor = new ForkExecutor();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenForkExecutor_whenExecuteRecursiveTask_thenResultOk() {
|
||||||
|
assertEquals(BigInteger.valueOf(3628800), forkExecutor.execute(new ForkFactorialTask(10, 5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenForkExecutor_whenExecuteCallable_thenResultOk() {
|
||||||
|
assertEquals(BigInteger.valueOf(126), forkExecutor.execute(Arrays.asList(new CallableFactorialTask(5), new CallableFactorialTask(3))));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user