一、简述
该模式的核心思想是异步调用。有点类似于异步的ajax请求。当调用某方法时,该方法耗时较久,而在主函数中也不急于立刻获取结果。因此可以让调用者立刻返回一个凭证,该方法放到另外线程执行,后续主函数拿凭证再去获取方法的执行结果即可,其结构图如下:
二、通过FutureTask实现
注意其中两个耗时操作:
1.如果doOtherThing耗时2s,则整个函数耗时2s左右。
2.如果doOtherThing耗时0.2s,则整个函数耗时取决于RealData.costTime,即1s左右结束。
public class FutureDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
return new RealData().costTime();
}
});
ExecutorService service = Executors.newCachedThreadPool();
service.submit(future);
System.out.println("RealData方法调用完毕");
// 模拟主函数中其他耗时操作
doOtherThing();
// 获取RealData方法的结果
System.out.println(future.get());
}
private static void doOtherThing() throws InterruptedException {
Thread.sleep(2000L);
}
}
public class RealData {
public String costTime() {
try {
// 模拟RealData耗时操作
Thread.sleep(1000L);
return "result";
} catch (InterruptedException e) {
e.printStackTrace();
}
return "exception";
}
}
三、通过Future实现
与上述FutureTask不同的是,RealData需要实现Callable接口。
public class FutureDemo1 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService service = Executors.newCachedThreadPool();
Future<String> future = service.submit(new RealData1());
System.out.println("RealData1方法调用完毕");
// 模拟主函数中其他耗时操作
doOtherThing();
// 获取RealData2方法的结果
System.out.println(future.get());
}
private static void doOtherThing() throws InterruptedException {
Thread.sleep(2000L);
}
}
public class RealData1 implements Callable {
public String costTime() {
try {
// 模拟RealData耗时操作
Thread.sleep(1000L);
return "result";
} catch (InterruptedException e) {
e.printStackTrace();
}
return "exception";
}
@Override
public String call() throws Exception {
return costTime();
}
}
另外Future本身还提供了一些额外的简单控制功能,其API如下:
// 取消任务
boolean cancel(boolean mayInterruptIfRunning);
// 是否已经取消
boolean isCancelled();
// 是否已经完成
boolean isDone();
// 取得返回对象
V get() throws InterruptedException, ExecutionException;
// 取得返回对象, 并可以设置超时时间
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
网友评论