1、Future
Future代表异步计算的结果。提供了检查计算是否完成、等待其完成以及检索计算结果的方法。只有在计算完成后,才能使用方法get检索结果,如有必要,将其阻塞,直到准备就绪。取消是通过取消方法执行的。还提供了其他方法来确定任务是否正常完成或被取消。
//等待异步任务完成,然后检索其结果
V get() throws InterruptedException, ExecutionException;
//最多等待给定的时间以完成计算,然后检索其结果
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
//如果此任务已完成,则返回true。完成可能是由于正常终止、异常或取消——在所有这些情况下,此方法将返回true
boolean isDone();
private static final ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
int i = 0;
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "test-" + i++);
}
});
public static void demo01() {
log.info("创建异步任务");
Future<String> submit = executor.submit(new Callable<String>() {
@Override
public String call() {
String result = "fail";
try {
log.info("开始执行异步任务");
// 执行任务耗时
Thread.sleep(10000);
result = "success";
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
});
try {
String result = submit.get();
log.info("获取异步任务结果 " + result);
} catch (InterruptedException e) {
System.out.println("中断异常");
} catch (ExecutionException e) {
System.out.println("执行异常");
}
log.info("Future的get方法,会使当前线程阻塞");
}
public static void demo02() throws InterruptedException, ExecutionException {
log.info("创建异步任务");
Future<String> submit = executor.submit(new Callable<String>() {
@Override
public String call() {
String result = "fail";
try {
log.info("开始执行异步任务");
// 执行任务耗时
Thread.sleep(10000);
result = "success";
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
});
log.info("轮询调用isDone方法查询异步任务是否完成");
while (true) {
if (submit.isDone()) {
String result = submit.get();
log.info(result);
break;
} else {
log.info("异步任务还未完成,先干点别的事");
Thread.sleep(1000);
}
}
log.info("Future的get方法,会使当前线程阻塞");
}
使用Future,并不能实现真正的异步,要么需要阻塞的获取结果,要么不断的轮询
2、CompletableFuture
CompletableFuture实现了CompletionStage接口和Future接口,增加了异步回调、流式处理、多个Future组合处理的能力,使Java在处理多任务的协同工作时更加顺畅便利。
//创建带返回值的异步任务,要么使用的默认线程池ForkJoinPool.commonPool(),要么入参时给定
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) {
return asyncSupplyStage(screenExecutor(executor), supplier);
}
//创建无返回值的异步任务,要么使用的默认线程池ForkJoinPool.commonPool(),要么入参时给定
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return asyncRunStage(asyncPool, runnable);
}
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) {
return asyncRunStage(screenExecutor(executor), runnable);
}
//如果以任何方式完成,则返回true:正常、异常或通过取消
public boolean isDone() {
return result != null;
}
//等待此任务完成,然后返回其结果
public T get() throws InterruptedException, ExecutionException {
Object r;
return reportGet((r = result) == null ? waitingGet(true) : r);
}
//最多等待给定的时间,以完成此任务,然后返回其结果
public T get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
Object r;
long nanos = unit.toNanos(timeout);
return reportGet((r = result) == null ? timedGet(nanos) : r);
}
//如果任务完成则返回结果集,否则返回给定的valueIfAbsent
public T getNow(T valueIfAbsent) {
Object r;
return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
}
thenApply / thenAccept / thenRun
在流式处理中,等待上层任务正常执行完成后,再执行回调方法;
thenApply:上层任务的结果值作为回调方法的入参值,该回调方法有返回值
thenAccept:上层任务的结果值作为回调方法的入参值,该回调方法没有返回值
thenRun:没有入参也没有返回值的回调方法
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) {
return uniApplyStage(null, fn);
}
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn) {
return uniApplyStage(asyncPool, fn);
}
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor) {
return uniApplyStage(screenExecutor(executor), fn);
}
public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
return uniAcceptStage(null, action);
}
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
return uniAcceptStage(asyncPool, action);
}
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor) {
return uniAcceptStage(screenExecutor(executor), action);
}
public CompletableFuture<Void> thenRun(Runnable action) {
return uniRunStage(null, action);
}
public CompletableFuture<Void> thenRunAsync(Runnable action) {
return uniRunStage(asyncPool, action);