Futuer 模式
Futrure模式
:对于多线程,如果线程A要等待线程B的结果,那么线程A没必要等待B,直到B有结果,可以先拿到一个未来的Future,等B有结果是再取真实的结果。
你可以那做饭来比喻,假如你突然想做饭,但是没有厨具,也没有食材。网上购买厨具比较方便,食材去超市买更放心。
实现分析:在快递员送厨具的期间,我们肯定不会闲着,可以去超市买食材。所以,在主线程里面另起一个子线程去网购厨具。然后等什么都准备好了,才能开始做饭。
公共数据接口,FutureData和RealData都要实现。
public interface Data {
public abstract String getRequest();
}
FutureData,当有线程想要获取RealData的时候,程序会被阻塞。等到RealData被注入才会使用getReal()方法。
public class FurureData implements Data {
public volatile static boolean ISFLAG = false;
private RealData realData;
public synchronized void setRealData(RealData realData) {
// 如果已经获取到结果,直接返回
if (ISFLAG) {
return;
}
// 如果没有获取到数据,传递真是对象
this.realData = realData;
ISFLAG = true;
// 进行通知
notify();
}
@Override
public synchronized String getRequest() {
while (!ISFLAG) {
try {
wait();
} catch (Exception e) {
}
}
// 获取到数据,直接返回
return realData.getRequest();
}
}
真实数据RealData
public class RealData implements Data {
private String result;
public RealData(String data) {
System.out.println("正在使用data:" + data + "网络请求数据,耗时操作需要等待.");
try {
Thread.sleep(3000);
} catch (Exception e) {
}
System.out.println("操作完毕,获取结果...");
result = "余胜军";
}
@Override
public String getRequest() {
return result;
}
FutureClient 客户端
public class FutureClient {
public Data request(String queryStr) {
FurureData furureData = new FurureData();
new Thread(()->{
RealData realData = new RealData(queryStr);
furureData.setRealData(realData);
}).start();
return furureData;
}
}
调用者:
public class Main {
public static void main(String[] args) {
FutureClient futureClient = new FutureClient();
Data request = futureClient.request("请求参数.");
System.out.println("请求发送成功!");
System.out.println("执行其他任务...");
String result = request.getRequest();
System.out.println("获取到结果..." + result);
}
}
调用者请求资源,client.request(“name”); 完成对数据的准备
当要获取资源的时候,data.getResult() ,如果资源没有准备好isReady = false;那么就会阻塞该线程。直到资源获取然后该线程被唤醒。
Callable获取任务结果
在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。Callable用来执行任务,产生结果。
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> future = executor.submit(new AddNumberTask());
System.out.println(Thread.currentThread().getName() + "线程执行其他任务");
Integer integer = future.get();
System.out.println(integer);
// 关闭线程池
if (executor != null){
executor.shutdown();
}
}
}
class AddNumberTask implements Callable<Integer> {
public AddNumberTask() {
}
public Integer call() throws Exception {
System.out.println("####AddNumberTask###call()");
Thread.sleep(5000);
return 5000;
}
}