Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑
核心思想:异步调用
我自己的拙见:在主程序中,我们要调用一个很费时的函数,我们需要用到这个函数的计算结果,才能继续执行下一步。这时候由于等待时间较长,影响程序的效率
这时候就采用Future模式,他先给主程序返回一个标识符,再开启线程去执行这个函数,而主程序可以不受影响的继续执行。等真实值计算出来,再通过刚刚的标识符去取得真实结果
Future模式的主要参与者如下表所示:
参 与 者 作 用
Main 系统启动,调用Client发出请求
Client 返回Data对象,立即返回futureData,并开启ClientThread线程装配Real
Data 返回数据的接口
Future Future数据,构造很快,但是是一个虚拟的数据,需要装配Real
Real 真实数据,其构造是比较慢的
给出流程如图(自己画的可能有错,,哈哈)
下面代码:
Main
package t;
public class Main {
public static void main(String[] args)
{
long starttime = System.currentTimeMillis();
System.out.println("发出请求");
Client client = new Client("放炮");
Data data = client.request();
System.out.println("请求已完成,正在准备中,请做出其他指示");
try {
for(int i=0;i<5;i++)
{
System.out.println("其他指示中————————————");
Thread.sleep(400);
}
System.out.println("准备完成:"+data.getData());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long endtime = System.currentTimeMillis() - starttime;
System.out.println("花费时间"+endtime);
}
}
Client
package t;
public class Client {
private String name; //请求的名字
public Client(String name) {
this.name = name;
}
public Data request() {
Future futureData = new Future();
new Thread() {
public void run(){
Real read = new Real();
futureData.setResult(read); //将计算完成的read 丢给futureData,
// 不然会不等计算完成就会先行执行这个方法
}
}.start();
return futureData;
}
}
Data
package t;
/*
- Data接口
*/
public interface Data {
public String getData();
}
Future
package t;
public class Future implements Data{
private boolean isReady = false; //判断状态
private String data; //装真实值
public synchronized void setResult(Real read) {
//解释一下为什么要用synchronized,
//如果不锁定代码块,会出现异常,至于为什么我个人也没想得太明白
//我觉得如果有多个进程去执行它,那么后面用到的notifyAll()会受影响吧
//有更好的解释请留言
if(isReady) //如果是true,说明赋值成功,所以return
{
return;
}
this.isReady = true; //否则就改变状态
this.data = read.getData(); //将得到的值赋值
notifyAll(); //提醒等待的程序,赋值成功
}
@Override
public synchronized String getData() {
while(!isReady) { //没准备完成一直在等待中
try { //说一下为什么要设置等待,在前面调用这个函数的时候
//如果不设置等待,就会返回一个空值
//当赋值成功,就会被唤醒
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return data;
}
}
Real
package t;
public class Real implements Data{
private String data;
public Real() {
String s = "1";
for(int i=0;i<50000;i++) //模拟放炮过程
{
s+=i;
}
this.data = "放炮已完成,请指示";
}
@Override
public String getData() {
return data;
}
}
以上就是个人的收获,如有错误请指正,谢谢