大家已经知道Future可以异步返回结果,但是其中的原理 却并不是所有人都懂 今天偶然看见了一段模拟原理的代码 就记录一下
首先大致介绍下其中的原理 : 在客户端请求的时候,直接返回客户端需要的数据(此数据不一定完整,只是简单的一点不耗时的操作),但是客户端并不一定马上使用所有的信息,此时就有了时间去完善客户需要的信息 大致原理如此 说到底就是一个简单的异步操作,下面贴上源码 并做简单的介绍:
一:首先创建数据接口 就一个简单的获取数据的方法:
public interface Data {
//定义一个获取结果的接口
String getRequest();
}
二:创建具体的接口实现类:
public class RealData implements Data {
// 获取的结果
private String result;
public RealData(String para) {
System.out.println("正在查询数据...");
try {
// 模拟 执行耗时的操作 实际操作中可能是查询数据库等
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查收数据完毕...");
result = "查询结果是:" + para;
}
@Override
public String getRequest() {
return result;
}
}
三:创建RealData 的代理类 持有一个RealData类 并且可以对其进行set和get
public class FutureData implements Data {
private RealData realData;
private volatile boolean isRead = false;
ReentrantLock r = new ReentrantLock();
Condition c = r.newCondition();
public void setRealData(RealData realData) {
// 判断是否已经查询出结果 有了就直接返回
if (isRead)
return;
// 没有结果 获取结果
r.lock();
this.realData = realData;
isRead = true;
c.signal();
r.unlock();
}
@Override
public String getRequest() {
r.lock();
//结果没有查询完毕 等待完成
while (!isRead) {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
r.unlock();
return this.realData.getRequest();
}
}
四:创建具体的客户端使用类 可以调用此方法获取结果
public class FutureClient {
public Data request(String para) {
//创建一个具体的数据类
final FutureData fd = new FutureData();
//创建异步线程 执行耗时的数据查询操作
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new Runnable() {
@Override
public void run() {
RealData realData = new RealData(para);
fd.setRealData(realData);
}
});
es.shutdown();
//直接返回结果
return fd;
}
}
五:模拟客户端调用 测试操作
public class Test {
public static void main(String[] args) {
FutureClient fc = new FutureClient();
Data data = fc.request("开始请求: test Data");
System.out.println("请求发送成功...");
System.out.println("获取到结果,但是并不马上使用:" + data);
String result = data.getRequest();
System.out.println(result);
}
}