版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/AnselLyy/article/details/80958377
Future 设计模式
欢迎访问 我的个人博客
概述
Future模式有点类似于商品订单。在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的是一直持续等待直到这个答复收到之后再去做别的事情,但如果利用Future模式,其调用方式改为异步,而原先等待返回的时间段,在主调用函数中,则可以用于处理其他事务。
Future模式的主要参与者
参与者 | 作用 |
---|---|
Main | 系统启动,调用Client发出请求 |
Client | 返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData |
Data | 返回数据的接口 |
FutureData | Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData |
RealData | 真实数据,其构造是比较慢的 |
JDK 内置的 Future 模式
由于Future是非常常用的多线程设计模式,因此在JDK中内置了Future模式的实现。
这些类在java.util.concurrent包里面。其中最为重要的是FutureTask类,它实现了Runnable接口,作为单独的线程运行。在其run()方法中,通过Sync内部类调用Callable接口,并维护Callable接口的返回对象。当使用FutureTask.get()方法时,将返回Callable接口的返回对象。
Future 接口提供的线程控制功能
boolean cancle(boolean mayInterruptIfRunning); // 取消任务
boolean isCancelled(); // 是否已经取消
boolean isDone(); // 是否已经完成
V get() throws InterruptedException, ExecutionException; //取得返回对象
V get(long timeout, TimeUnit unit); //取得返回对象,可以设置超时时间
Future 模式案例
public class FutureMode implements Callable<String> {
private String param;
public FutureMode(String param) {
// TODO Auto-generated constructor stub
this.param = param;
}
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 10; i++) {
stringBuffer.append(param);
// 通过 sleep 来模拟真实情况下的业务缓慢
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
return stringBuffer.toString();
}
public static void main(String[] args) {
FutureTask<String> futureTask = new FutureTask<>(new FutureMode("test"));
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.submit(futureTask);
System.out.println("请求完毕");
try {
// 模拟其他的业务操作
Thread.sleep(2000);
System.out.println("数据 = " + futureTask.get());
} catch (InterruptedException | ExecutionException e) {
// TODO: handle exception
} finally {
executorService.shutdown();
}
}
}