Callable
Runnable封装一个异步执行的任务,Callable和Runnable类似,但是有返回值,且可以抛出一个受检的异常。
public interface Callable<V>{
V call() throws Exception();
}
Future保存异步计算的结果,可以启动一个计算,将Future对象交给某个线程,然后忘记它。Future对象的所有者能够在计算结束时获取它。
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
Future的get方法能够阻塞,直到能获取结果。指定timeout的get方法在指定时间内未获取到结果就会抛出TimeoutException异常。
isCancelled方法返回任务是否已经取消,isDone返回任务是否已经完成。cancel方法取消未启动的任务,MayInterruptIfrunning参数为true时可以中断运行中的任务。(具体中断会不会取消,要看任务对中断的响应)
FutureTask是一个包装器,能够将Callable转换成Runnable和Future。这样就可以在Thread中使用Callable和Future带来的特性了(Thread只支持Runnable接口实例)。
@Test
public void testFt() throws InterruptedException, ExecutionException {
Callable<Integer> task = () -> {
Thread.sleep(1500);
return new Random().nextInt(1000);
};
FutureTask<Integer> future = new FutureTask<>(task);
new Thread(future).start();
System.out.println(future.isDone());
System.out.println("future result= " + future.get());
}
CompletableFuture
CompletableFuture是java8中添加的一个类,这个类主要的作用就是提供了新的方式来完成异步处理,包括合成和组合事件的非阻塞方式。
CompletableFuture类实现了CompletionStage和Future接口。Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种阻塞的方式显然和我们的异步编程的初衷相违背。
为了解决这个问题,JDK吸收了guava的设计思想,加入了Future的诸多扩展功能形成了CompletableFuture。
CompletionStage是一个接口,从命名上看得知是一个完成的阶段,它里面的方法也标明是在某个运行阶段得到了结果之后要做的事情。
示例:
@Test
public void testCompletableFuture() {
String res = CompletableFuture.supplyAsync(() -> "hello").thenApplyAsync((a) -> a + "world").join();
System.out.println(res);
}
- 为CompletableFuture添加一个动作
| 方法 | 参数 | 描述 |
|---|---|---|
| thenApply | T->U | 对结果应用一个函数 |
| thenCompose | T->CompletableFuture<U> | 对结果调用函数并执行返回的future |
| handle | (T,Throwable)-> U | 处理结果或错误 |
| thenAccept | T->void | 类似thenApply,不过结果为void |
| whenCompose | (T,Throwable)->void | 类似handle,不过结果为void |
| thenRun | Runnable | 执行Runnable,结果为void |
组合多个Future
- thenCombine|
- thenAcceptBoth
- runAfterBoth
- applyToEither
- acceptEither
- runAfterEither
- static allOf
- static anyOf