Future模式:是多线程设计常用的一种设计模式,类似商品订单。商品下单后,会立即得到下单成功的通知,客户不用等待后续商家的操作,只等配送到家即可,下单后到收到商品这段时间,客户可以做其他事情,不用在家等着商品。Future模式也类似Ajax的异步请求,不用等待处理结果。
与传统模式的比较
传统模式:客户端发出call请求,这个请求需要很长一段时间才能返回。客户端一直等待着,直到数据返回,随后进行其他业务处理。
Future模式:服务程序不需要等待数据处理完成便立即返回客户端伪造的数据(相当于商品的订单,而不是实际商品),客户端拿到这个返回结果后,并不急于对其处理,而是利用等待的时间,调用其他业务逻辑。这就是Future模式的核心所在。
主要参与者
MainOperate:系统启动,调用client发出请求。
Client:返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData。
Data:返回数据的接口。
FutureData:Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData。
RealData:真实数据,其构造过程是比较慢的。
package com.neo.study001.redio15;
/**
* @author liyy
* @date 2020/5/6 21:08
*/
public class MainOperate {
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);
}
}
package com.neo.study001.redio15;
/**
* @author liyy
* @date 2020/5/6 21:10
*/
public class FutureClient {
public Data request(final String param) {
FutureData fd = new FutureData();
new Thread(new Runnable() {
@Override
public void run() {
RealData realData = new RealData(param);
fd.setRealData(realData);
}
}).start();
return fd;
}
}
package com.neo.study001.redio15;
/**
* @author liyy
* @date 2020/5/6 21:11
*/
public interface Data {
String getRequest();
}
package com.neo.study001.redio15;
/**
* @author liyy
* @date 2020/5/6 21:22
*/
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();
}
}
package com.neo.study001.redio15;
/**
* @author liyy
* @date 2020/5/6 21:23
*/
public class RealData implements Data{
private String result;
public RealData(String param) {
System.out.println("根据请求参数:"+param+"进行查询,这是一个很耗时的操作");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("操作完毕,获取结果");
result="获取到的真实结果";
}
@Override
public String getRequest() {
return result;
}
}