- 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;
}
@Override
public 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() {
@Override
public 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();
}
@Override
public 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条数据";
}
@Override
public String getRequest() {
return result;
}
}