一、Future设计模式有什么好处
假如有一个执行起来需要花费一些时间的方法,为了省去不必要的等待执行结果出来,继续做别的事情,则可以事先获取一个“提货单”即Future参与者
二、Future的几个概念
- Future:未来,可以理解为票据,先获取这样一个票据,然后在未来的时刻里,通过票据,获取任务处理结果
- TASK:任务,比较重的任务
- FutureServer:桥接Future和TASK,会启动一个线程,单独执行TASK,待任务执行完,会改变Future状态,表明可以获取结果啦
三、例子
1.Future
public interface Future<T> {
T get() throws InterruptedException;
}
public class AsynFuture<T> implements Future<T> {
private T result;
private boolean done = false;
public void done(T result){
synchronized (this){
this.result = result;
this.done = true;
notifyAll();
}
}
@Override
public T get() throws InterruptedException {
synchronized (this){
while (!done){
wait();
}
}
return result;
}
}
2.Task
public interface FutureTask<T> {
T call();
}
3.FutureService
public class FutureService {
public <T> Future<T> submit(final FutureTask<T> task){
AsynFuture<T> asynFuture = new AsynFuture<>();
new Thread(()->{
T result = task.call();
asynFuture.done(result);
}).start();
return asynFuture;
}
public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer){
AsynFuture<T> asynFuture = new AsynFuture<>();
new Thread(()->{
T result = task.call();
asynFuture.done(result);
consumer.accept(result);
}).start();
return asynFuture;
}
}
4.client
public class SyncInvoker {
public static void main(String[] args) throws InterruptedException {
FutureService futureService = new FutureService();
// Future<String> future = futureService.submit(()->{
// try {
// Thread.sleep(10_000L);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// return "FINISH";
// });
futureService.submit(()->{
try {
Thread.sleep(10_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "FINISH";
}, System.out::println);
System.out.println("============");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("============");
//System.out.println( future.get());
System.out.println("============");
}
}
-
从上面例子,我们发现虽然在等待TASK时,主线程可以干其他的事情了。但如果future.get()后,就WAIT住了,不能在干其他事情了。有没有好的办法解决其问题呢,可以使用java8 consumer来解决此问题。让consumer主动通知主线程消费,而不是主线程主动尝试调用结果
-
现又多了个方式,等待多个线程结束的方案(在之前介绍了join, 观察者设计模式)