什么是Future模型:
该模型是将异步请求和代理模式联合的模型产物。类似商品订单模型。见下图:
客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据,程序先去执行其他的操作后,再去调用服务器已经完成组装的真实数据。该模型充分利用了等待的时间片段。
Future模式的核心结构:
Main:启动系统,调用Client发出请求;
FutureClient:返回Data对象,理解返回FutureData,并开启ClientThread线程装配RealData;
Data:返回数据的接口;
FutureData:Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData;
RealData:真实数据,构造比较慢。
代码实例
/** * @author mouliu * @create 2018-04-07-下午9:30 */public interface Data { String getRequest();}复制代码
/** * @author mouliu * @create 2018-04-07-下午9:31 */public class RealData implements Data { private String result; @Override public String getRequest() { return result; } public RealData(String queryStr){ System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作.."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("操作完毕,获取结果"); result = "查询结果"; }}复制代码
/** * @author mouliu * @create 2018-04-07-下午9:33 */public class FutureData implements Data { private RealData realData; private boolean isReady = false; public synchronized void setRealData(RealData realData){ //如果已经装载完毕了,就直接返回 if (isReady){ return; } //如果没有装载,进行装载真实对像 this.realData = realData; isReady = true; //进行通知 this.notify(); } @Override public String getRequest() { //如果没有状态好,程序就一直处于堵塞状态 while (!isReady){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } return this.realData.getRequest(); }}复制代码
public class FutureClient { public Data request(final String querStr){ //1 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他请求已经接收到,可以做其他的事情 final FutureData futureData = new FutureData(); //2 启动一个新的线程,去加载真实的数据,传递给这个代理对象 new Thread(new Runnable() { @Override public void run() { //3 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象 RealData realData = new RealData(querStr); futureData.setRealData(realData); } }).start(); return futureData; }}复制代码
public class Main { public static void main(String[] args){ FutureClient fc = new FutureClient(); Data data = fc.request("请求参数"); System.out.println("请求发送成功!"); System.out.println("做其他的事情..."); String result = data.getRequest(); System.out.println(result); }}复制代码
FutureData是RealData的包装,对真实数据的一个代理,封装了获取真实数据的等待过程。它们都实现了共同的接口,所以,针对客户端程序组是没有区别的;
客户端在调用的方法中,单独启用一个线程来完成真实数据的组织,这对调用客户端的main函数式封闭的;
因为咋FutureData中的notifyAll和wait函数,主程序会等待组装完成后再会继续主进程,也就是如果没有组装完成,main函数会一直等待。