33-案例实现
案例实现
根据如下步骤来实现本案例。
1.创建一个实现 Callable 接口且泛型为 String 的名为 ExecutableTask 的类:
public class ExecutableTask implements Callable<String> {
2.声明一个名为 name 的私有 String 型变量,用来存储任务名称。还要实现 getName() 方法来返回该变量的值:
private final String name;
public String getName(){
return name;
}
3.实现该类的构造方法,并初始化任务名称:
public ExecutableTask(String name){
this.name=name;
}
4.实现 call() 方法,让任务休眠一段随机时间并返回任务名称等信息:
@Override
public String call() throws Exception {
try {
long duration=(long)(Math.random()*10);
System.out.printf("%s: Waiting %d seconds for results.\n",
this.name,duration);
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException e) {}
return "Hello, world. I'm "+name;
}
5.实现一个名为 ResultTask 的类。该类继承 FutureTask 类,泛型类型为 String :
public class ResultTask extends FutureTask<String> {
6.声明一个名为 name 的私有 String 型变量,它用来存储任务名称:
private final String name;
7.实现该类的构造方法,该方法接收一个 Callable 实例对象作为参数。调用该类父类构造方法并使用接收的任务属性来初始化 name 变量:
public ResultTask(ExecutableTask callable) {
super(callable);
this.name= callable.getName();
}
8.重写 done() 方法。检查 isCancelled() 方法的值并根据返回值在控制台打印返回信息:
@Override
protected void done() {
if (isCancelled()) {
System.out.printf("%s: Has been canceled\n",name);
} else {
System.out.printf("%s: Has finished\n",name);
}
}
9.至此,我们可以开始实现应用程序的入口,创建包含 main() 方法的 Main 类:
public class Main {
public static void main(String[] args) {
10.使用 Executors 类中的 newCachedThreadPool 创建 ExecutorService 实例对象:
ExecutorService executor=Executors.newCachedThreadPool();
11.创建一个数组用来存储5个 ResultTask 对象:
ResultTask resultTasks[]=new ResultTask[5];
12.初始化 ResultTask 对象。对数组中的每个元素,首先创建 ExecutableTask 对象,并使用该对象创建 ResultTask 对象;随后使用 submit() 方法提交 ResultTask 对象到执行器:
for (int i=0; i<5; i++) {
ExecutableTask executableTask=new ExecutableTask("Task "+i);
resultTasks[i]=new ResultTask(executableTask);
executor.submit(resultTasks[i]);
}
13.让主线程休眠5s:
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
14.取消提交给执行器的全部任务:
for (int i=0; i<resultTasks.length; i++) {
resultTasks[i].cancel(true);
}
15.用 ResultTask 对象的 get() 方法获取还未取消的对象信息,并在控制台打印出来:
for (int i=0; i<resultTasks.length; i++) {
try {
if (!resultTasks[i].isCancelled()){
System.out.printf("%s\n",resultTasks[i].get());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
16.调用 shutdown() 方法关闭执行器:
executor.shutdown();
}
}