- Future模式,也是非常经典的设计模式,这种模式主要就利用空间换时间的概念,也就是说异步执行(需要开启一个新的线程)
- 在互联网高并发的应用服务中,我们随处可见这种理念和代码,主要就是使用了这种模式
- Future模式非常适合在处理耗时很长的业务逻辑时进行使用,可以有效的减小系统的响应时间,提高系统的吞吐量
package com.example.core.juc;import java.util.concurrent.*;public class UseFuture implements Callable<String> {private String param;public UseFuture(String param){this.param = param;}@Overridepublic String call() throws Exception{//模拟执行业务的耗时Thread.sleep(3000);String result = this.param =",处理完成";return result;}public static void main(String[] args) throws InterruptedException, ExecutionException {String queryStr1 = "query1";String queryStr2 = "query2";FutureTask<String> future1 = new FutureTask<String>(new UseFuture(queryStr1));FutureTask<String> future2 = new FutureTask<String>(new UseFuture(queryStr2));ExecutorService executorService = Executors.newFixedThreadPool(2);executorService.submit(future1);//异步的操作executorService.submit(future2);//异步的操作System.out.println("处理其他的任务");Thread.sleep(2000);String ret1 = future1.get();String ret2 = future2.get();System.out.println("数据处理完成"+ret1);System.out.println("数据处理完成"+ret2);
/*
output:
处理其他的任务
数据处理完成,处理完成
数据处理完成,处理完成*/}
}
future设计模式
- 最为关键的就是FutureData包装类,当客户端发出请求,FutureData会接收并返回请求,但是此时这个call return并不包含真是的数据,FutureData会发送other call去获取真实的数据类,再将真实的数据类返回,用于真正的实际使用。
- Future模式有点类似于商品订单。 比如在网购时,当看重某一件商品事,就可以提交订单,当订单处理完成后,在家里等待商品送货上门即可
- 或者说更形象的我们发送Ajax请求的时候,页面是异步的进行后台处理,用户无须一直等待请求的结果,可以继续浏览或操作其他内容
例子
- 网购时,当看重某一件商品事,就可以提交订单,当订单处理完成后,在家里等待商品送货上门即可
- 当客户端发起请求,返回包装类对象,另外起一个线程去查询数据,再将真实的数据返回
- Main.java
package com.example.core.future;public class Main {public static void main(String[] args) {FutureClient fc = new FutureClient();Data data = fc.request("请求参数");//异步执行System.out.println("做其他的相关业务操作");String rst = data.getRequest();//这才是真正的获取实际数据的方法System.out.println("---"+rst);}
}
/*
做其他的相关业务操作
根据查询参数:请求参数进行查询数据库操作这可能需要5秒左右的时间
---100条数据*/
- Data抽象层
package com.example.core.future;public interface Data {String getRequest();
}
- FutureClient.java
package com.example.core.future;public class FutureClient {public Data request(final String queryStr){FutureData futureData = new FutureData();//异步的起一个线程去进行相应的处理操作new Thread(new Runnable() {@Overridepublic void run() {//需要把请求的参数 设置到真实数据的处理对象中去RealData realData = new RealData(queryStr);//真实请求处理完成之后,我们需要进行设置,将结果给包装对象futureData.setRealData(realData);}}).start();;return futureData;}
}
- FutureData.java
package com.example.core.future;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;//真实的数据已经准备好了,我们进行唤醒操作notify();}@Overridepublic synchronized String getRequest() {while(!isReady){try{wait();}catch (InterruptedException e){e.printStackTrace();}}return this.realData.getRequest();}
}
- RealData.java
package com.example.core.future;public class RealData implements Data{private String result;public RealData(String queryStr){System.out.println("根据查询参数:"+queryStr+"进行查询数据库操作这可能需要5秒左右的时间");try{//时间的查询耗时Thread.sleep(5000);}catch (InterruptedException e){e.printStackTrace();}result = "100条数据";}@Overridepublic String getRequest() {return result;}
}