Future设计模式其实跟AJax请求有点相像,他无非就是在一个线程访问的时候,先返回一个假的,空壳的数据给客户端,然后后台再开启一个线程去执行任务,等到前台真正使用结果数据的时候,再返回真正的数据给客户端,如果此时数据没有加载完毕,就阻塞。这种模式不走业务逻辑,直接返回假的数据给客户端,然后自己开一个线程偷偷加载数据。
下面来看一个小案例:
设计一个Data接口,表示返回的数据,里面只有一个方法,获取返回结果:
package com.zkingsoft.future;
/**
* @Author Lee_Hoo
* @DATE Created in 2017/9/23
* @Description:
*/
public interface Data {
String getRequest();
}
设计一个实现类,这个是假的返回结果集,该实现类中两个方法,一个方法用于加载真是的结果集,第二个方法中如果真实结果没有加载完毕,那么调用getRequest()返回结果集方法将会被阻塞,这里使用isReady作为一个标识:
package com.zkingsoft.future;
/**
* @Author Lee_Hoo
* @DATE Created in 2017/9/23
* @Description:
*/
public class FutureData implements Data {
private RealData realData;
private boolean isReady = false;
public synchronized void setRealData(RealData realData) {
if(isReady==true){
return;
}
this.realData = realData;
isReady=true;
notify();
}
@Override
public synchronized String getRequest() {
while (!isReady){
try {
wait();
}catch (Exception e){
e.printStackTrace();
}
}
return this.realData.getRequest();
}
}
再来看看真实的RealData实现类干了什么:
package com.zkingsoft.future;
/**
* @Author Lee_Hoo
* @DATE Created in 2017/9/23
* @Description:
*/
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;
}
}
无外乎就是加载真正的数据了。
那么什么时候加载的真实的结果集呢?看看FutureClient类:
package com.zkingsoft.future;
/**
* @Author Lee_Hoo
* @DATE Created in 2017/9/23
* @Description:
*/
public class FutureClient {
public Data request(final String param){
final FutureData data = new FutureData();
new Thread(new Runnable() {
@Override
public void run() {
RealData realData = new RealData(param);
data.setRealData(realData);
}
}).start();
return data;
}
}
注意:直接返回了一个假的FutureData对象,偷偷开启了一个线程去加载真实的结果集。
测试类:Main:
package com.zkingsoft.future;
/**
* @Author Lee_Hoo
* @DATE Created in 2017/9/23
* @Description:
*/
public class Main {
public static void main(String[] args) {
FutureClient future = new FutureClient();
Data data = future.request("请求参数...");
System.out.println("请求发送成功...");
System.out.println("做其他的事情...");
String result = data.getRequest();
System.out.println(result);
}
}
输出结果:
D:\Java\jdk1.8.0_73\bin\java "-javaagent:D:\intellij\IntelliJ IDEA Community Edition 2017.2.4\lib\idea_rt.jar=50137:D:\intellij\IntelliJ IDEA Community Edition 2017.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Java\jdk1.8.0_73\jre\lib\charsets.jar;D:\Java\jdk1.8.0_73\jre\lib\deploy.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\access-bridge-64.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\cldrdata.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\dnsns.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\jaccess.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\jfxrt.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\localedata.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\nashorn.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\sunec.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\sunjce_provider.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\sunmscapi.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\sunpkcs11.jar;D:\Java\jdk1.8.0_73\jre\lib\ext\zipfs.jar;D:\Java\jdk1.8.0_73\jre\lib\javaws.jar;D:\Java\jdk1.8.0_73\jre\lib\jce.jar;D:\Java\jdk1.8.0_73\jre\lib\jfr.jar;D:\Java\jdk1.8.0_73\jre\lib\jfxswt.jar;D:\Java\jdk1.8.0_73\jre\lib\jsse.jar;D:\Java\jdk1.8.0_73\jre\lib\management-agent.jar;D:\Java\jdk1.8.0_73\jre\lib\plugin.jar;D:\Java\jdk1.8.0_73\jre\lib\resources.jar;D:\Java\jdk1.8.0_73\jre\lib\rt.jar;D:\intellij\并发编程\out\production\FutureMS;D:\intellij\IntelliJ IDEA Community Edition 2017.2.4\plugins\Kotlin\kotlinc\lib\kotlin-stdlib.jar;D:\intellij\IntelliJ IDEA Community Edition 2017.2.4\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;D:\intellij\IntelliJ IDEA Community Edition 2017.2.4\plugins\Kotlin\kotlinc\lib\kotlin-test.jar;D:\intellij\IntelliJ IDEA Community Edition 2017.2.4\plugins\Kotlin\kotlinc\lib\kotlin-stdlib-jre7.jar;D:\intellij\IntelliJ IDEA Community Edition 2017.2.4\plugins\Kotlin\kotlinc\lib\kotlin-stdlib-jre8.jar" com.zkingsoft.future.Main
请求发送成功...
做其他的事情...
根据请求参数...进行查询,这是一个很耗时的操作
加载完毕,返回结果
返回的结果集
Process finished with exit code 0