本章涉及的内容:
总结:(执行过程)
总结:生成一个随机数组
总结;
- 创建一个Fork/Join 池
- 插入任务的结果
- 同步运行任务
- 在任务中抛出异常
- 取消一个任务
1、在任务中抛出异常
package com.jack;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
public class Task extends RecursiveTask<Integer> {
/**
*
*/
private static final long serialVersionUID = 1L;
private int array[];
private int start ,end;
public Task(int[] array, int start, int end) {
super();
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
System.out.printf("任务: 开始从%d 到 %d\n", start, end);
if(end - start <10){
if((3>start) && (3<end)){
throw new RuntimeException("任务抛出一个异常从" + start+ "到" + end);
}
try {
TimeUnit.SECONDS.sleep(1);
}catch (InterruptedException e){
e.printStackTrace();
}
} else {
int mid = (end+start)/2;
Task task1 = new Task(array, start, mid);
Task task2 = new Task(array, mid , end);
invokeAll(task1, task2);
}
System.out.printf("任务: 结束形式 %d 到 %d\n", start, end);
return 0;
}
}
package com.jack;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
int array[] = new int[100];
Task task = new Task(array, 0,100);
ForkJoinPool pool = new ForkJoinPool();
pool.execute(task);
pool.shutdown();
try {
pool.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e){
e.printStackTrace();
}
if(task.isCompletedAbnormally()){
System.out.printf("Main: 一个异常已经抛出\n");
System.out.printf("Main: %s\n", task.getException());
}
System.out.printf("Main: 结果:%d", task.join());
}
}
总结:(执行过程)
- 1、创建一个任务task(实现了RecursiveTask<T>接口。
- 2、创建执行者。执行任务。关闭
- 3、防止Main主线程退出
- 4、获取异常
2、取消一个任务
以下两种情况需要考虑
1、ForkJoinPool类不会提供任何方法去取消正在运行或在池中等待的任务
2、当你取消一个任务的时候,你不能取消已经执行的任务。
package com.jack;
import java.util.Random;
public class ArrayGenerator {
public int[] generateArray(int size){
int array[] = new int[size];
Random random = new Random();
for(int i=0; i<size; i++){
array[i] = random.nextInt(10);
}
return array;
}
}
总结:生成一个随机数组
package com.jack;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinTask;
public class TaskManager {
private List<ForkJoinTask<Integer>> tasks;
public TaskManager(){
tasks = new ArrayList<>();
}
public void addTask(ForkJoinTask<Integer> task){
tasks.add(task);
}
public void cancelTasks(ForkJoinTask<Integer> cancelTask){
for(ForkJoinTask<Integer> task :tasks){
if(task!=cancelTask){
task.cancel(true);
((SearchNumberTask) task).writeCancelMessage();
}
}
}
}
总结:如果没有找数字就取消任务
package com.jack;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
public class SearchNumberTask extends RecursiveTask<Integer>{
/**
*
*/
private static final long serialVersionUID = 1L;
private int numbers[];
private int start,end;
private int number;
private TaskManager manager;
private final static int NOT_FOUND=-1;
public SearchNumberTask(int[] numbers, int start, int end, int number, TaskManager manager) {
super();
this.numbers = numbers;
this.start = start;
this.end = end;
this.number = number;
this.manager = manager;
}
@Override
protected Integer compute() {
System.out.printf("任务: %d : 结束\n" , start);
int ret;
if(end -start>10){
ret = launchTasks();
} else {
ret = lookForNumber();
}
return ret;
}
private int lookForNumber() {
for (int i=start; i<end; i++){
if(numbers[i] == number) {
System.out.printf("任务:数字 %d 找到 位置在%d\n", number, i);
manager.cancelTasks(this);
return i;
}
try{
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e){
e.printStackTrace();
}
}
return NOT_FOUND;
}
private int launchTasks() {
int mid = (start+end)/2;
SearchNumberTask task1 = new SearchNumberTask(numbers, start, mid, number, manager);
SearchNumberTask task2 = new SearchNumberTask(numbers, mid,end, number, manager);
manager.addTask(task1);
manager.addTask(task2);
task1.fork();
task2.fork();
int returnValue;
returnValue = task1.join();
if(returnValue!=-1){
return returnValue;
}
returnValue = task1.join();
return returnValue;
}
public void writeCancelMessage(){
System.out.printf("任务: 取消任务 从%d 到 %d \n", start, end);
}
}
查找数字,任务细分
package com.jack;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
ArrayGenerator generator = new ArrayGenerator();
int array[] = generator.generateArray(1000);
TaskManager manager = new TaskManager();
ForkJoinPool pool = new ForkJoinPool();
SearchNumberTask task = new SearchNumberTask(array, 0, 1000, 5, manager);
pool.execute(task);
pool.shutdown();
try {
pool.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.printf("Main : 执行完毕\n");
}
}
总结;
- 1、生成一个数组
- 2、创建任务管理来实现取消任务
- 3、创建任务对象SearchNumberTask
- 4、执行任务(如果没有找到数字的任务取消掉)
- 5、关闭ForkJoinPool
日志:
第五章完。。。。。。。。。。。。。。。