package com.fwz.tproject.serviceImpl;
/**
* Project Name:Spring0725
* File Name:ForJoinPollTask.java
* Package Name:work1201.basic
* Date:2017年12月4日下午5:41:46
* Copyright (c) 2017, 深圳金融电子结算中心 All Rights Reserved.
*
*/
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
import org.junit.Test;
/**
* ClassName:ForJoinPollTask <br/>
* Function: 对一个长度为100的元素值进行累加 Date: 2017年12月4日 下午5:41:46 <br/>
*
* @author prd-lxw
* @version 1.0
* @since JDK 1.7
* @see
*/
public class ForJoinPoolTask {
@Test
public void fork() throws Exception {
int[] arr = new int[100];
Random random = new Random();
int total = 0;
// 初始化100个数组元素
for (int i = 0, len = arr.length; i < len; i++) {
int temp = random.nextInt(20);
// 对数组元素赋值,并将数组元素的值添加到sum总和中
total += (arr[i] = temp);
}
System.out.println("初始化数组总和:" + total);
SumTask task = new SumTask(arr, 0, arr.length);
// 创建一个通用池,这个是jdk1.8提供的功能
ForkJoinPool pool = ForkJoinPool.commonPool();
Future<Integer> future = pool.submit(task); // 提交分解的SumTask 任务
System.out.println("多线程执行结果:" + future.get());
pool.shutdown(); // 关闭线程池
}
}
/**
* ClassName: SumTask <br/>
* Function: 继承抽象类RecursiveTask,通过返回的结果,来实现数组的多线程分段累累加 RecursiveTask 具有返回值 date:
* 2017年12月4日 下午6:08:11 <br/>
*
* @author prd-lxw
* @version 1.0
* @since JDK 1.7
*/
class SumTask extends RecursiveTask<Integer> {
private static final int THRESHOLD = 20; // 每个小任务 最多只累加20个数
private int arry[];
private int start;
private int end;
/**
* Creates a new instance of SumTask. 累加从start到end的arry数组
*
* @param arry
* @param start
* @param end
*/
public SumTask(int[] arry, int start, int end) {
super();
this.arry = arry;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
// 当end与start之间的差小于threshold时,开始进行实际的累加
if (end - start < THRESHOLD) {
for (int i = start; i < end; i++) {
sum += arry[i];
}
return sum;
} else {// 当end与start之间的差大于threshold,即要累加的数超过20个时候,将大任务分解成小任务
int middle = (start + end) / 2;
SumTask left = new SumTask(arry, start, middle);
SumTask right = new SumTask(arry, middle, end);
// 并行执行两个 小任务
left.fork();
right.fork();
// 把两个小任务累加的结果合并起来
return left.join() + right.join();
}
}
}