Main:启动系统,调用Client发出请求;
Client:返回Data对象,理解返回FutureData,并开启ClientThread线程装配RealData;
Data:返回数据的接口;
FutureData:Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData;
RealData:真实数据,构造比较慢。
(1)Data接口 ,提供getResult方法
public interface Data {
public String getResult();
}
(2)Future类实现,RealData的代理类,用于返回RealData的包装对象,封装了RealData的等待过程
/*
* 实现了一个快速返回RealData 的包装,但并非真实的返回结果。
*/
public class FutureData implements Data{
protected RealData realData=null; //FutureData是RealData的一个包装
protected boolean isReady=false;
public synchronized void setRealData(RealData realData)
{
if(isReady)
{
return;
}
this.realData=realData;
isReady=true;
notifyAll(); //当调用Future包装类的set方法时,线程RealData被唤醒,同个getResult()方法
}
@Override
public synchronized String getResult() { //会等待RealData构造完成
while(!isReady)
{
try{
wait(); //一直等待,直到RealData被注入
}catch (Exception e)
{}
}
return realData.result; //RealData的真实实现
}
}
(3)RealData类实现
public class RealData implements Data{
protected final String result;
public RealData(String para)
{
StringBuffer sb=new StringBuffer();
//模拟一个很慢的构造过程
for(int i=0;i<50;i++)
{
sb.append(para);
try {
Thread.sleep(100);//代替一个很慢的操作过程
} catch (Exception e) {
}
}
result=sb.toString();
}
public String getResult()
{
return result;
}
}
(4)Client实现,用于获取FutureData,开启RealData线程,在接收请求后,快速返回future
public class Client
{
public Data request(final String queryString)
{
final FutureData future=new FutureData();
new Thread() //RealData构建很慢,放到一个单独的线程中进行
{
public void run() {
RealData realData=new RealData(queryString);
future.setRealData(realData);
//调用future的set方法,直接return 并唤醒RealData线程进行数据构造};
}.start();
return future; //立即被返回
}
}
(5) Main方法实现
/*
* 主要负责调用client发起请求,并使用返回的数据
*/
public class Main {
public static void main(String[] args) {
Client client =new Client();
//这里会立即返回结果,因为得到的是FutureData 而非RealData
Data data=client.request("name");
System.out.println("请求完毕!");
System.out.println(data.toString());
try{
//代表对其他业务的处理
//在处理过程中,RealData被传剑,充分利用了等待时间
//Thread.sleep(2000);
System.out.println("我也在被处理哦");
}catch(Exception e)
{}
System.out.println("真实数据:"+data.getResult());
}
}
最后程序输出:
请求完毕!
it.max.thinking.FutureData@15db9742 --future对象
我也在被处理哦 --其他业务处理结果
真实数据:namenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename
3、Future模式总结
Future模式的核心在于去除了main函数中的等待时间,使得原本等待的时间用于处理其他业务,充分利用计算机资源。
主要通过代理future类实现和RealData同样的接口实现,所以在main调用getResult时两个类对于main调用是一样的,因为future中的线程wait,返回future数据后,唤醒线程,实例化RealData时调用构造方法,组装数据返回。在此过程中main利用等待时间调用其它业务方法。 在类似于商品购买等业务中Future模式应用广泛。
一句话总结:精彩无需等待,西瓜太大先捡着芝麻等西瓜。
二、JDK1.6的内置Future实现
在JDK源码中,关于并发的实现concurrent 包中,Future接口提供线程控制:取消任务、返回对象、设置超时时间,同样一个RealData类实现该接口,提供call方法组织真实业务数据;