为什么要有Future:
场景1: 你执行某一个IO磁盘读取方法,大批量数据读取耗时10s,你想要得到结果集,就需要等待10s【时间虚订】
代码实例如下:
package com.handsome.thread2study.chapter8;
/**
* @author jiangkunli
* @date 2020-07-13 1:33 上午
* @description 同步调用测试
*/
public class SyncInvoker {
public static void main(String[] args) throws InterruptedException {
String result = get();
// 需要等待10000ms得到结果
System.out.println(result);
}
private static String get() throws InterruptedException {
Thread.sleep(10000);
return "FINISH";
}
}
get方法的阻塞导致了调用方的阻塞,以至于调用方下面的一些方法无法执行!我们可否让友军来替我们保存返回对象,我们跟友军要的时候,友军即使给到正在执行的结果情况呢?
如何解决场景1中的问题?
代码实例:
package com.handsome.thread2study.chapter8;
/**
* @author jiangkunli
* @date 2020-07-13 1:38 上午
* @description 这是结果集的通知方
*/
public interface Future<T> {
T get() throws InterruptedException;
}
package com.handsome.thread2study.chapter8;
/**
* @author jiangkunli
* @date 2020-07-13 1:39 上午
* @description 用来实现Thread方法的接口
*/
public interface FutureTask<T> {
T call();
}
package com.handsome.thread2study.chapter8;
/**
* @author jiangkunli
* @date 2020-07-13 1:44 上午
* @description 异步执行器来吧FutureTask的进度告知Future的get
*/
public class AsyncFuture<T> implements Future<T>{
private volatile boolean done = false;
private T result;
public void done(T result){
synchronized (this){
this.result = result;
this.done = true;
this.notifyAll();
}
}
@Override
public T get() throws InterruptedException {
synchronized (this){
while (!done){
this.wait();
}
}
return result;
}
}
package com.handsome.thread2study.chapter8;
/**
* @author jiangkunli
* @date 2020-07-13 1:40 上午
* @description 传入线程的实现类
*/
public class FutureService {
public <T> Future<T> submit(final FutureTask<T> task){
AsyncFuture<T> asyncFuture = new AsyncFuture<>();
new Thread(() -> {
T result = task.call();
asyncFuture.done(result);
}).start();
return asyncFuture;
}
}
package com.handsome.thread2study.chapter8;
/**
* @author jiangkunli
* @date 2020-07-13 1:52 上午
* @description
*/
public class AsyncInvoker {
public static void main(String[] args) throws InterruptedException {
// 定义future的服务类
FutureService futureService = new FutureService();
// 启动线程 并实现线程中的call方法
Future<String> submit = futureService.submit(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "FINISH";
});
// 其他业务代码会正常执行!
System.out.println("=========================");
System.out.println("do other things");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("do finsh other things");
System.out.println("=========================");
System.out.println(submit.get());
}
}
这样实现不会影响其他的业务代码执行