16-案例实现
案例实现
根据如下步骤来实现本案例。
1.创建一个名为 Task
的类。声明并继承 RecursiveTask
类,泛型为 Integer
类:
public class Task extends RecursiveTask<Integer> {
2.声明一个名为 array
的私有 int
数组变量—用来模拟本例中将要处理的数组数据:
private int array[];
3.声明两个名为 start
和 end
的私有 int
变量,这些变量将决定任务处理数组中的哪些数据:
private int start, end;
4.实现该类的构造方法并初始化全部属性:
public Task(int array[], int start, int end){
this.array=array;
this.start=start;
this.end=end;
}
5.实现任务的 compute()
方法。因为 RecursiveTask
类的泛型为 Integer
类,所以该方法必须返回一个 Integer
型实例对象。首先,在控制台打印 start
和 end
的信息:
@Override
protected Integer compute() {
System.out.printf("Task: Start from %d to %d\n",start,end);
6.如果 start
和 end
所决定的待处理的元素个数小于 10
,则检查这批元素是否处于数组的前4个位置,如果符合要求,则抛出 RuntimeException
异常,否则让任务休眠1s:
if (end-start<10) {
if ((3>start)&&(3<end)){
throw new RuntimeException("This task throws an"+
"Exception: Task from "+start+" to "+end);
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
7.否则分割元素块为两部分,创建两个 Task
实例对象来处理这些元素块,并在池中调用 invokeAll()
方法来执行它们:
} 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("Task: Result form %d to %d: %d\n",
start,mid,task1.join());
System.out.printf("Task: Result form %d to %d: %d\n",
mid,end,task2.join());
}
8.在控制台打印 start
和 end
变量值,以此表明任务结束:
System.out.printf("Task: End form %d to %d\n",start,end);
9.任务返回 0
作为执行结果:
return 0;
10.至此,我们可以开始实现应用程序的入口,创建包含 main()
方法的 Main
类:
public class Main {
public static void main(String[] args) {
11.创建一个包含 100
个整数的数组:
int array[]=new int[100];
12.创建一个 Task
实例对象来处理该数组:
Task task=new Task(array,0,100);
13.使用默认的构造方法创建一个 ForkJoinPool
实例对象:
ForkJoinPool pool=new ForkJoinPool();
14.在池中调用 execute()
方法执行任务:
pool.execute(task);
15.调用 shutdown()
方法关闭 ForkJoinPool
类:
pool.shutdown();
16.调用 awaitTermination()
方法来等待任务执行完成。如果不关心任务返回结果的耗时,则传递 1
和 TimeUnit.DAYS
作为参数:
try {
pool.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
17.调用 isCompletedAbnormally()
方法检查任务或子任务是否抛出异常。当任务抛出异常时,在控制台打印出相关信息。使用 ForkJoinTask
类中的 getException()
方法获取异常:
if (task.isCompletedAbnormally()) {
System.out.printf("Main: An exception has ocurred\n");
System.out.printf("Main: %s\n",task.getException());
}
System.out.printf("Main: Result: %d",task.join());