[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:
lucaCambi77
2023-06-06 03:52:46 +02:00
committed by GitHub
parent 65ef7bae18
commit fe50b9192d
8 changed files with 252 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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;
}
}

View File

@@ -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)));
}
}