CompletableFuture

CompletableFuture可以进行异步调用,类似于js在的Promise


ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池,一般放在静态成员变量中
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
    //返回一个数据
    return 1;
},executorService).whenComplete((res, throwable) -> {
    //完成异步时获取返回值
    System.out.println("返回值是:"+res+",异常是:"+throwable);
}).exceptionally((throwable) -> {
    //接收异常,修改返回值
    System.out.println("获得到的异常是:"+throwable);
    return 10;//返回一个值替代原来的返回值
});

CompletableFuture的具体使用: 创建线程的方式四

感知返回值,接收异常,并修改返回值
上面的方式通过whenComplete方法感知结果的产生,并且能接收异常,但是不能修改返回值,如果要修改返回值,就得和上面的案例一样结合exceptionally方法才能达到效果。
handle方法

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池,一般放在静态成员变量中
CompletableFuture<Integer> exceptionally = CompletableFuture.supplyAsync(() -> {
    //返回一个数据
    return 1;
},executorService).handle((res,throwable)->{
    if (res==1){
        System.out.println("返回的结果是"+res);
        return 1;
    }
    if (throwable!=null){
        System.out.println("异常是"+throwable);
        return 0;
    }
    return 100;
});

情景一、异步两任务组合都完成,执行任务三

runAfterBoth方法无法感知任务一任务二是否完成

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池,一般放在静态成员变量中
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    return 1;
},executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
},executorService);
future1.runAfterBothAsync(future2,()->{
    System.out.println("联合任务1和2");
},executorService);

使用thenAcceptBothAsync会感知任务一和任务二都完成。

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池,一般放在静态成员变量中
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    return 1;
},executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
},executorService);
future1.thenAcceptBothAsync(future2,(result1,result2)->{
    System.out.println("感知任务一和任务二完成,执行任务三");
},executorService);

合并多个任务使用thenCombineAsync在上面的结果,基础上,如果想要有返回值则使用它

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    return 1;
},executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
});
future1.thenCombineAsync(future2,(res1,res2)->{
    System.out.println("感知任务完成,合并两个任务,返回一个新的结果");
    return res1+","+res2;
},executorService);

情景二、异步两任务只要有一个完成,就执行任务三

两个任务只要有一个完成就执行任务三的方法都是 XXXEither都带有Either
runAfterEitherAsync:不感知结果,并且无返回值

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    try {
        TimeUnit.MILLISECONDS.sleep(200);//让任务二晚点执行完,等任务二完成,任务三就会开始
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return 1;
},executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
});
future1.runAfterEitherAsync(future2,()->{
    System.out.println("任务三开始,任务一任务二只要有一个完成就会开始执行任务三");
},executorService);

acceptEitherAsync:感知结果,接收返回值并消费掉,不产生返回值

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    try {
        TimeUnit.MILLISECONDS.sleep(200);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return 1;
},executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
});
future1.acceptEitherAsync(future2,(res)->{
    System.out.println("感知结果执行任务三");//需要注意使用lambda表达式需要future1和future2返回值类型相同
},executorService);

applyToEitherAsync:感知返回值,转换返回值得到一个新的结果

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    try {
        TimeUnit.MILLISECONDS.sleep(200);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return 1;
},executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
});
future1.applyToEitherAsync(future2,(res)->{
    System.out.println("感知结果执行任务三");//需要注意使用lambda表达式需要future1和future2返回值类型相同
    return "新的返回值"+res*2;
},executorService);

情景三、多任务组合完成

allOf方法
如果使用下面的代码等待多任务完成。
问题一:是执行future1.get();时线程是堵塞的,因此future2.get();future3.get();都不能执行,这样会导致执行的时间不会是三个任务最大的时间,而是加上了多余堵塞的时间。
问题二:就是产生冗余代码

future1.get();
future2.get();
future3.get();
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    return 1;
},executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
});
CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务三开始");
    return 3;
}, executorService);
CompletableFuture<Void> allOf = CompletableFuture.allOf(future1, future2, future3);
try {
    allOf.get();//等待所有任务都完成
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

如果要获得每一个任务的返回结果还是需要使用future1.get();,future2.get(),future3.get()得到返回结果。


情景四、多任务组合只要有一个完成

anyOf

ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务一开始");
    return 1;
}, executorService);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务二开始");
    return 2;
});
CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务三开始");
    return 3;
}, executorService);
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future1, future2, future3);
try {
    anyOf.get();//获得完成的那个任务结果,其它任务的结果就获取不到,想要获取得调用各自得get
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

你可能感兴趣的:(java,#,线程,#,Java高级笔记)