package thread;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class Exercise30_15 {
public static void main(String[] args) {
final int SIZE = 9_000_000;
double[] list = new double[SIZE]; //double型数组
for (int i = 0; i < list.length; i++) //初始化赋值
list[i] = i;
//测试并行求和
long startTime = System.currentTimeMillis();
double sum = parallelSum(list);
long endTime = System.currentTimeMillis();
System.out.println("sum = " + sum);
System.out.println("The number of processors is " + Runtime.getRuntime().availableProcessors());
System.out.println("The time is " + (endTime - startTime) + " milliseconds");
//测试顺序求和
startTime = System.currentTimeMillis();
sum = sum(list);
endTime = System.currentTimeMillis();
System.out.println("\nsum = " + sum);
System.out.println("The sequential time is " + (endTime - startTime) + " milliseconds");
}
/** 顺序求和 */
public static double sum(double[] list) {
double sum = 0.0;
for (int i = 0; i < list.length; i++)
sum += list[i];
return sum;
}
/** 并行求和 */
public static double parallelSum(double[] list) {
RecursiveTask<Double> mainTask = new SumTask(list);
ForkJoinPool pool = new ForkJoinPool();
return pool.invoke(mainTask);
}
/** 内部类-求和任务 */
private static class SumTask extends RecursiveTask<Double> {
private static final int THRESHOLD = 500; //最小门槛
private double[] list; //求和数组
public SumTask(double[] list) {
this.list = list;
}
@Override
protected Double compute() {
if (list.length < THRESHOLD) { //数组长度小于门槛时,执行顺序求和
double sum = 0.0;
for (int i = 0; i < list.length; i++)
sum += list[i];
return sum;
} else { //执行并行求和
double[] firstHalf = new double[list.length / 2]; //前子数组
System.arraycopy(list, 0, firstHalf, 0, firstHalf.length);
int secondHalfLength = list.length - list.length / 2;
double[] secondHalf = new double[secondHalfLength]; //后子数组
System.arraycopy(list, list.length / 2, secondHalf, 0, secondHalfLength);
//创建递归任务
RecursiveTask<Double> left = new SumTask(firstHalf);
RecursiveTask<Double> right = new SumTask(secondHalf);
//分解任务
left.fork();
right.fork();
//返回任务的联和
return left.join() + right.join();
}
}
}
}