26-案例实现
案例实现
根据如下步骤来实现本案例。
1.创建一个 MyWorkerTask
类并指定它扩展 ForkJoinTask<Void>
类:
public abstract class MyWorkerTask extends ForkJoinTask<Void> {
2.声明一个名为 name
的私有字符串字段来存储任务的名称:
private String name;
3.实现该类的构造方法以初始化其字段:
public MyWorkerTask(String name) {
this.name=name;
}
4.实现 getRawResult()
方法。这是 ForkJoinTask
类的抽象方法之一。由于 MyWorkerTask
任务不会返回任何结果,因此该方法必须返回 null
:
@Override
public Void getRawResult() {
return null;
}
5.实现 setRawResult()
方法。这是 ForkJoinTask
类的另一个抽象方法。由于 MyWorkerTask
任务不会返回任何结果,因此此方法的主体会留空:
@Override
protected void setRawResult(Void value) {
}
6.实现 exec()
方法,这是任务的主要方法。在这种情况下,将任务的逻辑委托给 compute()
方法。计算此方法的执行时间并将其打印到控制台中:
@Override
protected boolean exec() {
Date startDate=new Date();
compute();
Date finishDate=new Date();
long diff=finishDate.getTime()-startDate.getTime();
System.out.printf("MyWorkerTask: %s : %d Milliseconds to
complete.\n",name,diff);
return true;
}
7.实现 getName()
方法以返回任务的名称:
public String getName(){
return name;
}
8.声明抽象方法 compute()
。如前所述,此方法将实现任务的逻辑,而且它必须由 MyWorkerTask
类的子类来实现:
protected abstract void compute();
9.创建一个 Task
类来扩展 MyWorkerTask
类:
public class Task extends MyWorkerTask {
10.声明一个整型的 array
私有数组:
private int array[];
11.实现该类的构造方法来初始化其字段:
public Task(String name, int array[], int start, int end){
super(name);
this.array=array;
this.start=start;
this.end=end;
}
12.实现 compute()
方法。此方法会增加由开始和结束字段确定的数组元素块。如果这个元素块有超过100个元素,则将块分成两部分并创建两个 Task
对象来处理每个部分。使用 invokeAll()
方法将这些任务发送到线程池:
protected void compute() {
if (end-start>100){
int mid=(end+start)/2;
Task task1=new Task(this.getName()+"1",array,start,mid);
Task task2=new Task(this.getName()+"2",array,mid,end);
invokeAll(task1,task2);
13.如果元素块中的元素少于100个,则使用 for
循环递增所有元素:
} else {
for (int i=start; i<end; i++) {
array[i]++;
}
}
14.最后,将执行任务的线程休眠50ms:
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
15.接下来,通过创建一个 Main
类和 main()
方法来实现本案例的主类:
public class Main {
public static void main(String[] args) throws Exception {
16.创建一个包含10000个元素的 int
数组:
int array[]=new int[10000];
17.创建一个名为 pool
的 ForkJoinPool
对象:
ForkJoinPool pool=new ForkJoinPool();
18.创建一个 Task
对象来增加数组中的元素。而其构造方法的参数分别赋值给 Task
作为任务的名称、数组对象,0值和10000值这两个数值意味着该任务必须处理整个数组:
Task task=new Task("Task",array,0,array.length);
19.使用 execute()
方法将任务发送到池:
pool.execute(task);
20.使用 shutdown()
方法关闭线程池:
pool.shutdown();
21.在控制台打印一条消息,以代表程序运行结束:
System.out.printf("Main: End of the program.\n");