CompletableFuture简介与使用

CompletableFuture

这个completableFuture是JDK1.8版本新引入的类。下面是这个类。实现了俩接口。本身是个class。这个是Future的实现类。
使用completionStage接口去支持完成时触发的函数和操作。
一个completetableFuture就代表了一个任务。他能用Future的方法。还能做一些之前说的executorService配合futures做不了的。
之前future需要等待isDone为true才能知道任务跑完了。或者就是用get方法调用的时候会出现阻塞。而使用completableFuture的使用就可以用then,when等等操作来防止以上的阻塞和轮询isDone的现象出现

那就先介绍一下Future和Callable借口
代码:

public class FutureDemo {
     
    public static void main(String[] args) throws Exception {
     
        // 创建实现了Callable接口的实例
        CallableDemo callableDemo = new CallableDemo();
        // 于实现了Future接口的实现类 来接收返回的结果  我们一般用FutureTask
        FutureTask<Integer> futureTask = new FutureTask<>(callableDemo);
        // 运行该线程
        new Thread(futureTask).start();
        // 获取结果
        // 有两种方式
        // 1. get
        /*
         *  如果线程没有执行完结果
         *  这里会出现阻塞
         */
        Integer integer = futureTask.get();
        System.out.println("integer = " + integer);

        // -----------------------我是华丽的分割线----------------------

        // 2.isDone
        // 创建实现了Callable接口的实例
        CallableDemo callableDemo1 = new CallableDemo();
        // 于实现了Future接口的实现类 来接收返回的结果  我们一般用FutureTask
        FutureTask<Integer> futureTask1 = new FutureTask<>(callableDemo1);
        // 运行该线程
        new Thread(futureTask1).start();
        // 判读线程
        while (!futureTask.isDone()) {
     
            TimeUnit.SECONDS.sleep(1);
        }
        Integer integer1 = futureTask.get();
        System.out.println("integer = " + integer1);

    }
}

/**
 * 1. 实现Callable可以很值一个泛型 这个泛型就是方法的返回值 并且这个方法可以抛出异常
 * 2. 执行callable方式 需要FutureTask实现类 支持  用于接收运算结果  FutureTask是 Future接口的实现类
 */
class CallableDemo implements Callable<Integer> {
     
    @Override
    public Integer call() throws Exception {
     
        int sum = 0;
        for (int i = 0; i < 100; i++) {
     
            sum += i;
        }
        return sum;
    }
}

CompletableFuture: 相比上面的方法不需要轮循 或 阻塞 在异步方法执行完成 再去执行另一个方法
总结一下优点:
·异步任务结束时,会自动回调某个对象的方法
·异步任务出错时,会自动回调某个对象的方法
·主线程设置好回调后,不再关心异步任务的执行


    public static void main(String[] args) throws ExecutionException, InterruptedException {
     
        // 创建一个CompletableFuture   CompletableFuture.supplyAsync异步的 他的参数是一个 Supplier函数式借口 提供一个子任务
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
     
            try {
     
                TimeUnit.SECONDS.sleep(1);
                int i = 10 / 0;
            } catch (InterruptedException e) {
     
                e.printStackTrace();
            }
            return "执行完成 lamdba 执行完成";
        });

        // 子任务执行成功 回调给方法 参数是一个 Consumer的 函数式接口
        cf.thenAccept(result -> {
     
            System.out.println("子任务执行成功");
            System.out.println("result = " + result);
        });

        // 子任务执行成功失败 回调这个方法  参数是一个 Function函数式借口
        cf.exceptionally(e -> {
     
            System.out.println("e = " + e.getMessage());
            return "子任务执行成功失败";
        });
        cf.join();
    }

穿行执行多个CompletableFuture

   public static void main(String[] args) throws Exception {
     
        // 创建一个CompletableFuture   CompletableFuture.supplyAsync异步的 他的参数是一个 Supplier函数式借口 提供一个子任务
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
     
            try {
     
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
     
                e.printStackTrace();
            }
            return "执行完成 lamdba 执行完成 一号";
        });

        CompletableFuture<String> cf1 = cf.thenApplyAsync((result) -> {
     
            try {
     
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
     
                e.printStackTrace();
            }
            return result + " | 执行完成 lamdba 执行完成 二号";
        });

        // 子任务执行成功 回调给方法 参数是一个 Consumer的 函数式接口
        cf1.thenAccept(result -> {
     
            System.out.println("子任务执行成功");
            System.out.println("result = " + result);
        });
        cf1.join();
    }

并行执行多个CompletableFuture
anyOf
连个必须都执行成功 一个执行失败就 执行exceptionally 方法 哪一个先执行成功 使用哪一个

    public static void main(String[] args) throws Exception {
     

        // 创建一个CompletableFuture   CompletableFuture.supplyAsync异步的 他的参数是一个 Supplier函数式借口 提供一个子任务
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
     
            try {
     
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
     
                e.printStackTrace();
            }
            return "执行完成 lamdba 执行完成 一号";
        });

        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
     
            try {
     
                TimeUnit.SECONDS.sleep(0);
                int i = 10 / 0;
            } catch (InterruptedException e) {
     
                throw new RuntimeException("");

            }
            return " | 执行完成 lamdba 执行完成 二号";
        });
        CompletableFuture<Object> cf2 = CompletableFuture.anyOf(cf, cf1);

        // 子任务执行成功 回调给方法 参数是一个 Consumer的 函数式接口
        cf2.thenAccept(result -> {
     
            System.out.println("子任务执行成功");
            System.out.println("result = " + result);
        });
        // 子任务执行成功失败 回调这个方法  参数是一个 Function函数式借口
        cf2.exceptionally(e -> {
     
            System.out.println("e = " + e.getMessage());
            throw new RuntimeException("出现异常了");
        });
        cf2.join();
    }

allOf
连个必须都执行成功 一个执行失败就 执行exceptionally 方法
最后的CompletableFuture 的泛型必须是 Void

  public static void main(String[] args) throws Exception {
     

        // 创建一个CompletableFuture   CompletableFuture.supplyAsync异步的 他的参数是一个 Supplier函数式借口 提供一个子任务
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
     
            try {
     
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
     
                e.printStackTrace();
            }
            return "执行完成 lamdba 执行完成 一号";
        });

        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
     
            try {
     
                TimeUnit.SECONDS.sleep(0);
            } catch (InterruptedException e) {
     
                throw new RuntimeException("");

            }
            return " | 执行完成 lamdba 执行完成 二号";
        });
        //
        CompletableFuture<Void> cf2 = CompletableFuture.allOf(cf, cf1);

        // 子任务执行成功 回调给方法 参数是一个 Consumer的 函数式接口
        cf2.thenAccept(result -> {
     
            System.out.println("子任务执行成功");
            System.out.println("result = " + result);
        });
        // 子任务执行成功失败 回调这个方法  参数是一个 Function函数式借口
        cf2.exceptionally(e -> {
     
            System.out.println("e = " + e.getMessage());
            throw new RuntimeException("出现异常了");
        });
        cf2.join();
    }

CompletableFuture的命名规则:
xxx():继续在已有的线程中执行
xxxAsync():Executor的新线程执行

CompletableFuture对象可以指定异步处理流程:
thenAccept()处理正常结果
exceptional()处理异常结果
thenApplyAsync()用于串行化另一个CompletableFuture
anyOf / allOf用于并行化两个CompletableFuture

你可能感兴趣的:(Java8,java,多线程)