聊聊CompletableFuture

      自从java8引入了Stream、函数式编程、CompletableFuture等特性之后,给我们码代码提供了不少酷炫的操作。从JDK1.5开始我们就可以通过Future接口实现异步,主要是创建一个线程池,然后提交Runnable或者Callable的任务。然后可以用get来获取返回结果(执行完毕才会返回),传统回调最大的问题就是不能将控制流分离到不同的事件处理器中。而CompletableFuture弥补了缺陷。本文主要讲CompletableFuture相关的特性。

     根据下面这行代码可以看出CompletableFuture实现了Future,CompletionStage。说明CompletableFuture既有保留了Future的特性,又通过CompletableFuture进行了扩展。

public class CompletableFuture<T> implements Future<T>, CompletionStage<T>

1.函数式接口     

       观察CompletableFuture代码,可以看出方法参数都是函数式接口,这个比较切合jdk1.8的编码风格。因此,我们可以先了解一下何为函数式编程。函数式编程就是通过lambda表达式进行简化编码。符合函数编程的接口叫函数式接口,函数式接口有一个特性,就是只能有一个抽象方法,在jdk1.8中函数式接口除了仅有的一个抽象方法,还可以拥有default缺省方法或者static静态方法。以下介绍几个函数式接口。

1.Function<T, R>:一个输入一个返回,stream中的map方法的入参就是该函数式接口

     该接口的核心抽象方法:R apply(T t);调用该方法的输入参数是T,返回结果是R。示例如下:

public static void main(String[] args){
        Function<String,Integer> function = a->{
            return Integer.parseInt(a);
        };
        System.out.println(function.apply("5"));
    }

2.Supplier<T>:没有输入,有一个返回

该接口的核心抽象的方法:T get();示例如下:

Supplier<Integer> supplier = ()->{
            return 5;
        };
        System.out.println(supplier.get());

3.Predicate<T>:一个输入参数,返回布尔值,stream中该函数式接口作为filter的入参。

该接口的核心抽象的方法:boolean test(T t);示例如下:

Predicate<Integer> predicate = a->{
            return a==5;
        };
        System.out.println(predicate.test(5));

4.Consumer<T>:一个输入,没有返回,stream中的foreach使用该接口作为输入。

该接口的核心的方法是:void accept(T t);示例如下:

Consumer<Integer> consumer = a->{
            System.out.println(a);
        };
        consumer.accept(5);

5.BiConsumer<T, U>:两个输入,没有输出。同Consumer<T>,区别在于输入参数个数不同。

示例如下:

 BiConsumer<Integer,Integer> biConsumer = (a,b)->{
            System.out.println(a+b);
        };
        biConsumer.accept(5,3);

6.BiFunction<T, U, R>:两个输入,有输出。同Function<T,R>,区别在于输入参数个数不同。

BiFunction<Integer,Integer,String> biFunction = (a,b)->{
            return String.valueOf(a+b);
        };
        System.out.println(biFunction.apply(4,5));

2.CompletableFuture实战

     由于CompletableFuture实现了Future接口和CompletionStage接口。所以保持了两个接口的特性的基础上进行了扩展,CompletableFuture类的主要特性方法如下:

  1.创建实例

        创建实例的方法如下:



#异步,提供一个supplier对象生成CompletableFuture对象
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return asyncSupplyStage(asyncPool, supplier);
    }


#异步,提供一个supplier对象生成CompletableFuture对象,该异步线程在指定
#线程池消费
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                       Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }


public static CompletableFuture<Void> runAsync(Runnable runnable) {
        return asyncRunStage(asyncPool, runnable);
    }

    

public static CompletableFuture<Void> runAsync(Runnable runnable,
                                                   Executor executor) {
        return asyncRunStage(screenExecutor(executor), runnable);
    }




#同步,给定一个值封装成CompletableFuture对象
public static <U> CompletableFuture<U> completedFuture(U value) {
        return new CompletableFuture<U>((value == null) ? NIL : value);
    }


2.串行执行



#同步
public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);


public CompletionStage<Void> thenAccept(Consumer<? super T> action);

public CompletionStage<Void> thenRun(Runnable action);

public <U> CompletionStage<U> thenCompose
        (Function<? super T, ? extends CompletionStage<U>> fn);

#异步

public <U> CompletionStage<U> thenApplyAsync
        (Function<? super T,? extends U> fn);
   
public <U> CompletionStage<U> thenApplyAsync
        (Function<? super T,? extends U> fn,
         Executor executor);


public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);

    
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,
                                                 Executor executor);


public CompletionStage<Void> thenRunAsync(Runnable action);

   
public CompletionStage<Void> thenRunAsync(Runnable action,
                                              Executor executor);



public <U> CompletionStage<U> thenComposeAsync
        (Function<? super T, ? extends CompletionStage<U>> fn);

   
public <U> CompletionStage<U> thenComposeAsync
    (Function<? super T, ? extends CompletionStage<U>> fn,
       Executor executor);

3.AND汇聚关系




#同步

public <U,V> CompletionStage<V> thenCombine
        (CompletionStage<? extends U> other,
         BiFunction<? super T,? super U,? extends V> fn);

public <U> CompletionStage<Void> thenAcceptBoth
        (CompletionStage<? extends U> other,








#异步
public <U,V> CompletionStage<V> thenCombineAsync
        (CompletionStage<? extends U> other,
         BiFunction<? super T,? super U,? extends V> fn);

    
public <U,V> CompletionStage<V> thenCombineAsync
        (CompletionStage<? extends U> other,
         BiFunction<? super T,? super U,? extends V> fn,
         Executor executor);

public <U> CompletionStage<Void> thenAcceptBothAsync
        (CompletionStage<? extends U> other,
         BiConsumer<? super T, ? super U> action);


public <U> CompletionStage<Void> thenAcceptBothAsync
        (CompletionStage<? extends U> other,
         BiConsumer<? super T, ? super U> action,
         Executor executor);

4.OR汇聚关系

 



#同步
public <U> CompletionStage<U> applyToEither
        (CompletionStage<? extends T> other,
         Function<? super T, U> fn);

public CompletionStage<Void> acceptEither
        (CompletionStage<? extends T> other,
         Consumer<? super T> action);


public CompletionStage<Void> runAfterEither(CompletionStage<?> other,
                                                Runnable action);






#异步
public <U> CompletionStage<U> applyToEitherAsync
        (CompletionStage<? extends T> other,
         Function<? super T, U> fn);

public <U> CompletionStage<U> applyToEitherAsync
        (CompletionStage<? extends T> other,
         Function<? super T, U> fn,
         Executor executor);

public CompletionStage<Void> acceptEitherAsync
        (CompletionStage<? extends T> other,
         Consumer<? super T> action);

public CompletionStage<Void> acceptEitherAsync
        (CompletionStage<? extends T> other,
         Consumer<? super T> action,
         Executor executor);

public CompletionStage<Void> runAfterEitherAsync
        (CompletionStage<?> other,
         Runnable action);
public CompletionStage<Void> runAfterEitherAsync
        (CompletionStage<?> other,
         Runnable action,
         Executor executor);


5示例实战

实体类student

public class Student {

    private String name;

    private int age;

    private String stuId;

    public Student(String name,int age,String stuId){
        this.name=name;
        this.age=age;
        this.stuId=stuId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getStuId() {
        return stuId;
    }

    public void setStuId(String stuId) {
        this.stuId = stuId;
    }

    public String toString(){
        return "student[name="+name+",age="+age+",stuId="+stuId+"]";
    }
}

工具类StudentUtil

public class StudentUtil {


    public static String getName(Student student){
        return "completableFuture:"+student.getName();
    }
}

实例:以下将上述常见的方法进行举例介绍

public class UserTestDemo {

    private static Map<String,User> map = new ConcurrentHashMap<>();


    private static List<User> list = new ArrayList<>();
    static {
        map.put("1000",new User("Bob",24));
        map.put("1001",new User("Curry",34));
        map.put("1002",new User("Amy",35));
        list.add(map.get("1000"));
        list.add(map.get("1001"));
        list.add(map.get("1002"));
    }

    public static CompletableFuture<User> getUser(String id){
        //创建一个future
        CompletableFuture<User> completableFuture = CompletableFuture.supplyAsync(()->{
            try {
                Thread.sleep(new Random().nextInt(10));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return map.get(id);
        });
        return completableFuture;
    }

    public static CompletableFuture<List<User>> combine(CompletableFuture<User> userCompletableFuture,String id){
        //合并
        return getUser(id).thenCombine(userCompletableFuture,(a,b)->{
            List<User> list = new ArrayList<>();
            list.add(a);
            list.add(b);
            return list;
        });
    }


    public static void main(String[] args){
        //创建一个future
        CompletableFuture<User> userCompletableFuture = getUser("1000");
        System.out.println(userCompletableFuture.isDone());
        //合并
        CompletableFuture<List<User>> listCompletableFuture = combine(userCompletableFuture,"1001");
        System.out.println("thenCombine:"+listCompletableFuture.join());
        userCompletableFuture.thenAccept(r-> {
            System.out.println(r.getName()+" is "+r.getAge());
        });
        System.out.println(userCompletableFuture.isDone());

        //合并 and Executor
        ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
        CompletableFuture<List<User>> listCompletableFutureExecutor = userCompletableFuture.thenCombineAsync(getUser("1001"),(a,b)->{
            List<User> list = new ArrayList<>();
            list.add(a);
            list.add(b);
            return list;
        },executor);
        System.out.println("executorAndCombine:"+listCompletableFutureExecutor.join());

        //or
        CompletableFuture<User> orCompletableFuture = getUser("1001").applyToEitherAsync(getUser("1000"),r->{
            return r;
        });
        System.out.println("orUser:"+orCompletableFuture.join());

        CompletableFuture<User> userCompletableFuture1 = getUser("1001");
        //apply
        CompletableFuture<Student> studentCompletableFuture = userCompletableFuture1.thenApplyAsync(r->{
            return new Student(r.getName(),r.getAge(),"1000000");
        });
        System.out.println("apply:"+studentCompletableFuture.join());
        System.out.println("apply:"+studentCompletableFuture.join());
        System.out.println("apply:"+studentCompletableFuture.isDone());


        CompletableFuture<Student> studentCompletableFutureAsync = userCompletableFuture1.thenApplyAsync(r->{
            try {
                Thread.sleep(10);
                System.out.println("aaaa");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new Student(r.getName(),r.getAge(),"1000000");
        });
        System.out.println(studentCompletableFuture.join());
        System.out.println("abcd");



        //map and thenCompose
        List<CompletableFuture<String>> userNameList  = list.stream()
                .map(r->CompletableFuture.supplyAsync(()->r.toStudent(String.valueOf(new Random().nextInt(1000)))))
                .map(r->r.thenComposeAsync(student->CompletableFuture.supplyAsync(()-> StudentUtil.getName(student))))
                .collect(Collectors.toList());
        List<String> nameList = userNameList.stream().map(CompletableFuture::join).collect(Collectors.toList());
        System.out.println("thenCompose:"+nameList);





    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值