一、Future模式的核心:
去除主函数的等待时间,并让原本需要等待的时间段用于处理其他的业务逻辑。
对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再去取真实的结果。
首先客户端向服务器请求RealSubject,但这个资源的创建非常耗时,这时返回Client端一个FutureSubject满足客户端的请求,同时,Future会通过创建一个Thread去真正的获取资源,资源准备完毕后,再给Future一个通知。但是如果客户端必须马上获取这个真正的资源,那么就会阻塞客户端的其他所有线程,等待资源准备完毕。
二、Future模式的实现
Data接口:返回数据的接口
public interface Data {
public String getResult();
}
RealSubject:真实的数据,其构造时比较慢的
public class RealSubject implements Data {
protected final String result;
public RealSubject(String para) {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < 10; i++){
sb.append(para);
try {
//用线程去模拟真实数据的构造
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
result = sb.toString();
}
@Override
public String getResult() {
return result;
}
}
FutureData:Future数据,构造很快,但是是一个虚拟的数据,需要装配RealSubject
public class FutureData implements Data {
protected RealSubject realData = null;
protected boolean isReady = false;
public synchronized void setRealData(RealSubject realData){
if(isReady){
return ;
}
this.realData = realData;
isReady = true;
notifyAll();
}
@Override
public String getResult() {
while (!isReady){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return realData.result;
}
Thread:启动线程,去获取数据
public class ClientThread {
public Data request(final String queryStr){
final FutureData futureData = new FutureData();
new Thread(){
public void run(){
RealSubject realData = new RealSubject(queryStr);
futureData.setRealData(realData);
}
}.start();
return futureData;
}
}
public class Client {
public static void main(String[] args){
ClientThread clientThread = new ClientThread();
Data data = clientThread.request("name");
System.out.println("request over");
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("data = " + data.getResult());
}
}
三、总结:
Future模式核心就是去除等待时间。我们可以这么理解,Future模式本身可看做是一个显示引用和一个异步处理结果的引用。由于其异步性,未返回真实数据时,此时对象不可用,我们可以利用这段时间去处理其他业务,或进入其他分支,直到返回真实数据,再进行处理。