核心思想
调用方式为异步,去除了主函数中的等待时间,主函数可去处理其他任务,如图:
代码实现
参与者 | 作用 |
---|---|
Main | 主函数,调用Client发出请求 |
Client | 返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData |
Data | 返回数据的接口 |
FutureData | 虚拟数据,构造很快 |
RealData | 真实数据,构造较慢 |
代码示意:
public static void main(String[] args)
{
Client client = new Client();
//立即返回,得到FutureData
Data data=client.request("name");
System.out.println("请求完毕");
//用sleep代表执行其他业务逻辑
Thread.sleep(2000);
//使用真实数据RealData
System.out.println(data.getResult());
}
//Data接口
public interface Data
{
public String getResult();
}
//Client类
public class Client
{
public Data request(String str)
{
FutureData fd = new FutureData();
//RealData构造很慢,单独开线程构造
new Thread()
{
public void run()
{
RealData rd = new RealData(str);
fd.setRealData(rd);
}
}.start();
return fd;
}
}
//FutureData类
public class FutureData implements Data
{
//FutureData是对RealData的包装
protected RealData rd = null;
protected boolean isReady=false;
public synchronized void setRealData(RealData rd)
{
if(isReady)
{
return;
}
this.rd=rd;
isReady=true;
notifyAll();
}
//会等待RealData构造完成
public synchronized String getResult()
{
while(!isReady)
{
//此类中可能有其他多线程任务,被唤醒的原因不一定是RealData构造完成,所以需要循环判断isReady是否真的构造完成
wait();
}
return rd.getResult();
}
}
//RealData类
public class RealData implements Data
{
private String result=null;
public RealData()
{
//构造数据,假设很慢
result = new String("xxxxxx");
}
public String getResult()
{
return result;
}
}
JDK内置实现
想要异步执行的业务逻辑放在call()方法内
代码示意:
public class RealData implements Callable<String>
{
private String para;
public RealData(String para)
{
this.para=para;
}
//真实业务逻辑
@Override
public String call()
{
//构造数据,假设很慢
return new String("xxxx");
}
}
public class Main
{
public static void main(String[] args)
{
FutureTask<String> future = new FutureTask<String>(new RealData("a"));
ExecutorService exe = Executors.newFixedThreadPool(1);
//开启线程执行RealData的call()方法,相当于2中的client.request()
exe.submit(future);
System.out.println("请求完毕");
//用sleep代表执行其他业务逻辑
Thread.sleep(5000);
//使用真实数据,相当于2中的data.getResult(),如果call()没有执行完,依然会等待
System.out.println(future.get());
}
}