Parallel Programming
Factorial of a number
Approach using parallel programming with the Fork/Join Framework to calculate the factorial of a number. This approach divides the factorial computation into smaller tasks that can be executed concurrently, leveraging the power of multi-core CPUs.
import java.math.BigInteger;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
public class ParallelFactorial extends RecursiveTask<BigInteger> {
private final int start, end;
private static final int THRESHOLD = 10; // Determines the granularity of the tasks.
// Constructor
public ParallelFactorial(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected BigInteger compute() {
// If the range is small enough, calculate directly.
if ((end - start) <= THRESHOLD) {
return calculateFactorialRange(start, end);
} else {
// Split the task into two subtasks.
int mid = (start + end) / 2;
ParallelFactorial leftTask = new ParallelFactorial(start, mid);
ParallelFactorial rightTask = new ParallelFactorial(mid + 1, end);
// Fork the left task and compute the right task.
leftTask.fork();
BigInteger rightResult = rightTask.compute();
BigInteger leftResult = leftTask.join();
// Combine results.
return leftResult.multiply(rightResult);
}
}
// Helper method to calculate factorial for a range.
private BigInteger calculateFactorialRange(int start, int end) {
BigInteger result = BigInteger.ONE;
for (int i = start; i <= end; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
// Main method to compute the factorial.
public static BigInteger computeFactorial(int n) {
ForkJoinPool pool = ForkJoinPool.commonPool(); // Use the common ForkJoinPool.
return pool.invoke(new ParallelFactorial(1, n));
}
public static void main(String[] args) {
int number = 100; // Change this number as needed.
BigInteger factorial = computeFactorial(number);
System.out.println("Factorial of " + number + " is: " + factorial);
}
}
RecursiveTask:
Extends
RecursiveTask<BigInteger>
for tasks that return a value.The
compute()
method recursively splits the task until the range is smaller than the threshold.
Threshold:
Determines when the task is small enough to compute sequentially.
A smaller threshold increases parallelism but adds overhead for task creation.
Fork/Join:
fork()
: Starts the left subtask asynchronously.compute()
: Computes the right subtask synchronously.join()
: Waits for the left subtask to complete and retrieves its result.
Range Calculation:
The range of numbers is divided and processed independently.
ForkJoinPool:
Manages and executes tasks across multiple threads.
Last updated
Was this helpful?