Future接口
定义了操作异步任务执行的一些方法,比如获取异步任务的执行结果 取消任务的执行 判断任务是否被i取消 判断任务执行是否完成。
异步执行任务的三个特点 多线程 有返回结果 异步任务。
FutureTask get()方法在计算完之前会一直阻塞,isDone方法浪费cpu资源
completableFuture提供了一种观察者模式的机制,可以让任务执行完后通知监听的一方。
completableFuture实现的接口CompletionStage
该接口代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另一个阶段
一个阶段的计算执行可以是一个Function、Consumer或者Runnable。
一个阶段的执行可能被单个阶段的完成触发 也可能有多个阶段一起触发。
CompletableFuture核心的四个静态方法
runAsync无返回值 supplyAsync有返回值 默认自带ForkJoinPool线程池
CompletableFuture常用方法分类
对计算结果进行处理
thenApply 计算结果存在依赖关系 这两个线程串行化,出现异常 由于存在依赖关系 当前步骤错了 不走下一步,当前步骤有异常的话叫停执行。
对计算结果进行消费
thenAccept 接收任务的处理结果,并消费处理,无返回结果
对比补充
CompletableFuture和线程池的说明
没有自定义线程池 都用默认的线程池
传入一个自定义的线程池时 如果执行的第一个任务的时候调用thenRun方法执行第二个任务,则第二个任务和第一个任务使用的是同一个线程池。如果调用thenRunAsync执行第二个任务时,则第一个 任务使用的是自定义线程池,第二个 任务还是使用的默认的线程池。
有可能处理太快 系统优化切换原则 直接使用main线程处理
对计算速度进行选用
applyToEither谁执行的快选择谁的结果使用
对执行结果合并
两个completionStage任务都完成后,最终能把两个任务的结果一起交给thenCombine来处理
以上的说明的实例代码
import java.util.concurrent.*;
public class CompletableFutureDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "a";
});
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "b";
});
CompletableFuture<String> stringCompletableFuture = a.thenCombine(b, (x,y)-> {
return x+y+"合并了结果啊";
});
System.out.println(stringCompletableFuture.get());
}
private static void demo04() throws InterruptedException, ExecutionException {
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "a";
});
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "b";
});
CompletableFuture<String> stringCompletableFuture = a.applyToEither(b, f -> {
return f + "win le ";
});
System.out.println(stringCompletableFuture.get());
}
private static void demo03() {
CompletableFuture.supplyAsync(() -> {
return 1;
}).thenApply(f->{
return f+1;
}).thenAccept(r->{
System.out.println(r);
});
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void demo02() {
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
}).thenApply(f -> {
return f + 1;
}).thenApply(f -> {
return f + 1;
}).whenComplete((f, e) -> {
if (e == null) {
System.out.println("执行结果" + f);
}
}).exceptionally(e -> {
System.out.println("执行异常" + e.getMessage());
return null;
});
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void demo01() {
ExecutorService executorService = Executors.newFixedThreadPool(3);
try {
CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + "-----come in");
int result = ThreadLocalRandom.current().nextInt(10);
try{TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e){e.printStackTrace();}
System.out.println("-----1分钟出结果" + result);
if (result > 2) {
int i = 1 / 0;
}
return result;
},executorService).whenComplete((i, e) -> {
if (e == null) {
System.out.println("执行完返回的结果" + i);
}
}).exceptionally(e->{
throw new RuntimeException("发生异常"+e.getMessage());
});
System.out.println(integerCompletableFuture.get());
System.out.println("执行其他任务");
}catch (Exception e){
System.out.println("发生异常了 需要抓取"+e.getMessage());
}finally {
executorService.shutdown();
}
}
}