61 lines
1.4 KiB
Java
61 lines
1.4 KiB
Java
package parallel;
|
|
|
|
import util.Prime;
|
|
import util.PrimeCounter;
|
|
import java.util.concurrent.ForkJoinPool;
|
|
import java.util.concurrent.RecursiveTask;
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
|
|
public class ForkJoinPoolPrimeCounter implements PrimeCounter {
|
|
|
|
private static final int SEQUENTIAL_THRESHOLD = 1000;
|
|
private final int numThreads;
|
|
|
|
public ForkJoinPoolPrimeCounter(int numThreads) {
|
|
this.numThreads = numThreads;
|
|
}
|
|
|
|
public int countPrimes(int[] nums) {
|
|
final ForkJoinPool p = new ForkJoinPool();
|
|
return p.invoke(new CountPrimes(nums, 0, nums.length - 1));
|
|
}
|
|
|
|
private static class CountPrimes extends RecursiveTask<Integer> {
|
|
|
|
private final int low, high;
|
|
private final int[] nums;
|
|
|
|
public CountPrimes(int[] nums, int low, int high) {
|
|
this.nums = nums;
|
|
this.low = low;
|
|
this.high = high;
|
|
}
|
|
|
|
@Override
|
|
protected Integer compute() {
|
|
if (low > high) {
|
|
return 0;
|
|
}
|
|
if ((high - low) <= SEQUENTIAL_THRESHOLD) {
|
|
int count = 0;
|
|
for (int i = low; i <= high; i++) {
|
|
if (Prime.isPrime(nums[i])) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
else {
|
|
final int mid = low + (high - low) / 2;
|
|
|
|
final CountPrimes leftTask = new CountPrimes(nums, low, mid);
|
|
final CountPrimes rightTask = new CountPrimes(nums, mid + 1, high);
|
|
|
|
rightTask.fork();
|
|
|
|
return leftTask.compute() + rightTask.join();
|
|
}
|
|
}
|
|
}
|
|
}
|