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();
}
}