转载:https://blog.51cto.com/13666149/2091152
https://www.jianshu.com/p/444cbe1691be
序言
有时候会遇到一种情况,当流程到了某个一个节点的时候,数据处理需要花费比较长的时间。只是在最后返回成功或者失败的时候体现,数据处理的结果并不影响后面流程的进展,现在介绍一种设计模式来充分利用时间片段,这个设计模式就是-Future设计模式。
之前的流程图
上图显示的是一个串行程序调用的流程,可以看出当有一个程序执行的操作比较耗时的时候,后面的程序必须等待该模块的执行完成,才能继续往下执行。
Future的设计模式流程图
Future的设计模式可以看出,主线程直接跳过了耗时的子线程,整个流程没有长时间的等待操作,充分利用了耗时的时间片段,提高了系统的执行效率,与用户的体验。
每个角色说一下
1、Main:启动系统,调用Client发出请求;
2、Client:返回Data对象,理解返回FutureData,并开启ClientThread线程装配RealData;
3、Data:返回数据的接口;
4、FutureData:Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData;
5、RealData:真实数据,构造比较慢。
理解:
future设计模式的关键是futureClient,做了一个承上启下的作用,对于主线程请求交给其他线程处理 ,主线程去做其他的事。这个设计模式使用的关键点在因为需要有一个返回值来为后期所调用,因为线程本身不能有返回值。所以有了futureData来得到数据,RealData是真实操作的类。
public interface Data {
String getRequest();
}
public class RealData implements Data {
private String result;
public RealData(String request) {
System.out.println("根据" + request + "进行查询..,要花很久时间");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("操作完毕,获取结果");
result = "查询结果";
}
public String getRequest() {
return result;
}
}
public class FutureData implements Data {
private RealData realData;
private boolean isReady = false;
public synchronized String getRequest() {
while (!isReady) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return this.realData.getRequest();
}
public synchronized void setRealData(RealData realData) {
if (isReady) {
return;
}
this.realData = realData;
isReady = true;
notify();
}
}
public class FutureClient {
public Data request(final String request) {
final FutureData futureData = new FutureData();
new Thread(new Runnable() {
public void run() {
RealData realData = new RealData(request);
futureData.setRealData(realData);
}
}).start();
return futureData;
}
}
public class Main {
public static void main(String[] args) {
FutureClient fClient = new FutureClient();
Data data = fClient.request("hello,world");
System.out.println("请求发送成功...");
System.out.println("干其他的事情...");
String result = data.getRequest();
System.out.println(result);
}
}