使用线程池的好处:
 1、降低资源的消耗
 通过重复利用已经创建好的线程降低线程的创建和销毁带来的损耗
 2、提高响应速度
 因为线程池中的线程数没有超过线程池的最大上限时,有的线程处于等待分配任务
 的状态,当任务来时无需创建新的线程就能执行
 3、提高线程的可管理性
 线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来
 的系统开销。无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使
 用线程池进行统一分配
以下代码首先创建线程池executor ,将其传入异步编排对象CompletableFuture,它提供了四个静态方法来创建一个异步操作。
1、创建异步对象方法

1、runXxxx 都是没有返回结果的,supplyXxx 都是可以获取返回结果的
2、可以传入自定义的线程池,否则就用默认的线程池
 
public class Thread1Test {
    public static ExecutorService executor = Executors.newFixedThreadPool(10);
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("方法开始。。。");
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println(i);
        }, executor);
        System.out.println("方法结束");
    }
}
 

2、计算完成时回调方法
使用supplyAsync可以获得线程运行返回结果:
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果"+i);
            return i;
        }, executor);
        Integer integer = future.get();
 
提供了计算完成时回调方法,在处理完成后,对结果进行操作:
 
 whenComplete 可以处理正常和异常的计算结果,exceptionally 处理异常情况。
 whenComplete 和 whenCompleteAsync 的区别:
 whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。
 whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池
 来进行执行。
 方法不以 Async 结尾,意味着 Action 使用相同的线程执行,而 Async 可能会使用其他线程
 执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)
 whenComplete可以得到任务完成结果,参数1是结果,参数2是异常:
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果"+i);
            return i;
        }, executor).whenComplete((res,excption)->{
            System.out.println("异步完成,结果是"+res+"异常是:"+excption);
        });
 
这里制造除数为0的异常:
 
 exceptionally虽然能得到异常信息,但是没法修改返回数据,感知异常,返回默认值
 CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果"+i);
            return i;
        }, executor).whenComplete((res,excption)->{
            System.out.println("异步完成,结果是"+res+"异常是:"+excption);
        }).exceptionally(throwable -> {
            //感知异常,返回默认值
            return 10;
        });
        Integer integer = future.get();
 

3、handle方法

 handle和 complete 一样,可对结果做最后的处理(可处理异常),可改变返回值。
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getId());
            int i = 10 / 4;
            System.out.println(i);
            return i;
        }, executor).handle((res,thr)->{
            if (res!=null){
                return res *2;
            }
            if (thr!=null){
                return 0;
            }
            return 1;
        });
 

4、线程串行化方法

 thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前
 任务的返回值。
 thenAccept 方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
 thenRun 方法:只要上面的任务执行完成,就开始执行 thenRun,只是处理完任务后,执行
 thenRun 的后续操作
 带有 Async 是多开一个线程,是异步执行的。同之前。
 以上都要前置任务成功完成。
      //线程串行化
        /* 1、 thenRunAsync 不能获取上一步的执行结果
           2、 thenAcceptAsync 能接受上一步结果,但无返回值
           3、 thenApplyAsync能接受上一步结果,有返回值
        * */
 CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getId());
            int i = 10 / 4;
            System.out.println("运行结果"+i);
            return i;
        }, executor).thenApplyAsync(res -> {
            System.out.println("任务2启动了" + res);
            return "hello" + res;
        }, executor);
 

5、两任务组合 - 都要完成

 两个任务必须都完成,触发该任务。
runAfterBoth:组合两个 future,不需要获取 future 的结果,只需两个 future 处理完任务后,
 处理该任务。
CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程" + Thread.currentThread().getId());
            int i = 10 / 4;
            System.out.println("任务1线程结束"+i);
            return i;
        }, executor);
        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程" + Thread.currentThread().getId());
            System.out.println("任务2线程结束");
            return "hello";
        }, executor);
        future01.runAfterBothAsync(future02,()->{
            System.out.println("任务3开始");
        },executor);
        System.out.println("方法结束");
 

 thenAcceptBoth:组合两个 future,获取两个 future 任务的返回结果,然后处理任务,没有
 返回值。
future01.thenAcceptBothAsync(future02,(f1,f2)->{
           System.out.println("任务3开始...之前的结果"+f1+f2);
       },executor);
 

thenCombine:组合两个 future,获取两个 future 的返回结果,并返回当前任务的返回值
 CompletableFuture<String> future = future01.thenCombineAsync(future02, (f1, f2) -> {
            return "组合处理任务1、2的结果" + f1 + f2 + "999";
        }, executor);
 

6、两任务组合 - 一个完成

runAfterEither:两个任务有一个执行完成,不需要获取 future 的结果,处理任务,也没有返
 回值。
 future01.runAfterEitherAsync(future02,()->{
           System.out.println("任务3开始前的结果");
       },executor);
 

 acceptEither:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值。
future01.acceptEitherAsync(future02,(res)->{
            System.out.println("任务3开始前的结果"+res);
        },executor);
 

 applyToEither:两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。
CompletableFuture<String> eitherAsync = future01.applyToEitherAsync(future02, (res) -> {
            System.out.println("任务3开始前结果" + res);
            return res.toString() + "--->" + "ke";
        }, executor);
        System.out.println("方法结束"+eitherAsync.get());
 

7、多任务组合

allOf:等待所有任务完成
  CompletableFuture<String> img = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品信息");
            return "hello.jpg";
        },executor);
        CompletableFuture<String> attr = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询属性信息");
            return "黑丝";
        },executor);
        CompletableFuture<String> desc = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
                System.out.println("查询商品介绍");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "油量";
        },executor);
        CompletableFuture<Void> allOf = CompletableFuture.allOf(img, attr, desc);
        allOf.get();
        System.out.println("任务结束"+img.get()+attr.get()+desc.get());
 

 anyOf:只要有一个任务完成
 CompletableFuture<Object> anyOf = CompletableFuture.anyOf(img, attr, desc);
 




















