Future设计模式
如果有任务执行需要比较长的时间,通常需要等待任务执行结束或者出错才能返回结果,在此期间调用者只能陷入阻塞苦苦等待,对此,Future设计模式提供了一种凭据式解决方案。可以先提交任务,立即返回一个凭据,调用者可稍后凭借凭借查询执行结果。
接口定义
Future
提交任务后会返回该接口,用于查询执行结果。
]public interface Future<T> {
T get() throws InterruptedException;
boolean done();
}
Task<IN,OUT>
如果执行的任务有返回值,则需要使用该接口提交任务。
public interface Task<IN,OUT> {
OUT get(IN input);
}
FutureService<In,OUT>
该接口用于提交任务,会返回一个Future用来稍后查询任务结果
public interface FutureService<In,OUT> {
Future<?> submit(Runnable runnable);
Future<?> submit(Task<In,OUT> task,In input);
static <T,R> FutureService<T,R> newService(){
return new FutureServiceImpl<T, R>();
}
}
接口实现
在任务结束后,会调用该类的finish方法。将isDone置为true并且为result赋值(线程执行结果)。
调用者可以使用get方法来得到结果。
public class FutureTask<T> implements Future<T> {
private T result;
private boolean isDone = false;
private final Object LOCK = new Object();
@Override
public T get() throws InterruptedException {
synchronized (LOCK){
while(!isDone){
LOCK.wait();
}
}
return result;
}
public void finish(T result){
synchronized (LOCK){
if(isDone){
return;
}
this.result=result;
this.isDone=true;
LOCK.notifyAll();
}
}
@Override
public boolean done() {
return isDone;
}
}
该类的submit方法用于提交任务(Runnable 或Task都可以),之后返回一个 FutureTask<>。
public class FutureServiceImpl<IN,OUT> implements FutureService<IN,OUT> {
private final static String FUTURE_THREAD_PREFIX="FUTURE-";
private final AtomicInteger nextCounter = new AtomicInteger(0);
private String getNextName(){
return FUTURE_THREAD_PREFIX+nextCounter.getAndIncrement();
}
@Override
public Future<?> submit(Runnable runnable) {
final FutureTask<Void> future = new FutureTask<Void>();
new Thread(()->{
runnable.run();
future.finish(null);
},getNextName()).start();
return future;
}
@Override
public Future<?> submit(Task<IN, OUT> task, IN input) {
final FutureTask<OUT> future = new FutureTask<OUT>();
new Thread(()->{
OUT result =task.get(input);
future.finish(result);
},getNextName()).start();
return future;
}
}
自JDK1.5起,Java提供了比较强大的Future接口,在JDK1.8时更引入了CompletableFuture,其结合函数式接口可实现更强大的功能。