核心思想
异步调用。先拿到一个Future,然后根据Future拿真实数据。
示例1
public interface Data {
String getResult();
}
/**
* 这是关键类,包装了RealData,代替RealData先返回。
* 通过该类获取RealData,如果RealData结果出来则直接返回,如果还没有则阻塞等待。
*/
public class FutureData implements Data {
/**包装RealData*/
protected RealData realData = null;
protected boolean isReady = false;
public synchronized void setRealData(RealData realData) {
if (isReady) {
return;
}
this.realData = realData;
this.isReady = true;
// RealData已经被注入,通知getResult()
notifyAll();
}
@Override
public synchronized String getResult() {
// 等待RealData构造完成
while (!isReady) {
try {
// 一直等待,RealData被注入
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return realData.getResult();
}
}
public class RealData implements Data {
protected final String result;
public RealData(String result) {
// RealData的构造可能很慢,需要等待很久,这里使用Sleep模拟。
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.result = result;
}
@Override
public String getResult() {
return result;
}
}
public class Client {
public Data request(String queryStr) {
FutureData futureData = new FutureData();
//RealData构建很慢,单开线程。
new Thread(()->{
RealData realData = new RealData(queryStr);
futureData.setRealData(realData);
}).start();
//FutureData立即返回
return futureData;
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Client client = new Client();
//立即返回得到的是FutureData,稍后通过这个FutureData的getResult获取RealData
Data data = client.request("baozi-request");
//这里模拟其他业务的处理,在这个过程中RealData慢慢构建成功
Thread.sleep(2000);
System.out.println("获取RealData:"+data.getResult());
}
}
示例2 JDK内置
FutureTask代替Callable先返回,稍后通过FutureTask获取Callable获取的数据。
import java.util.concurrent.Callable;
public class RealData implements Callable<String> {
@Override
public String call() throws Exception {
//RealData的构造可能很慢,需要等待很久,这里使用Sleep模拟。
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "callable";
}
}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<String> futureTask = new FutureTask<String>(new RealData());
ExecutorService es = Executors.newFixedThreadPool(1);
// FutureTask执行Callable,开启线程进行RealData的call执行
es.submit(futureTask);
// 这里模拟其他业务的处理,在这个过程中RealData慢慢构建成功
Thread.sleep(2000);
// 再次说明,先构建FutureTask,然后通过FutureTask执行Callable获取返回值
// 1.如果Callable没有返回则等待,2.已返回则返回
System.out.println("call:"+futureTask.get());
es.shutdown();
}
}