Java并发------JDK8 CompletableFuture

一、runAsync 和 supplyAsync

1、runAsync 的基本使用:无返回值,持有一个 Runnable 对象。

System.out.println("begin");
CompletableFuture.runAsync(() -> {
    try {
        System.out.println("before sleep");
        TimeUnit.MILLISECONDS.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("after sleep");
});
System.out.println("end");

异步任务会执行,但是主线程不回等待异步任务返回结果,也就是不会阻塞当前线程。

输出结果:

begin
end
before sleep

2、supplyAsync 的基本使用:有返回值,持有一个 Supplier 对象。

System.out.println("begin");
CompletableFuture<Person> supplyAsync = CompletableFuture.supplyAsync(() -> {
    System.out.println("before sleep");
    try {
        TimeUnit.MILLISECONDS.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("after sleep");
    return new Person();
});
System.out.println("before supplyAsync");
Person person = supplyAsync.get();
System.out.println("after supplyAsync");
System.out.println("end");

只有在调用 get() 方法时,才会执行异步任务,并且带有阻塞当前线程的效果。

输出结果:

begin
before supplyAsync
before sleep
after sleep
after supplyAsync
end

二、thenApply、thenAccept、thenRun

thenAccept、thenRun 这两个方法一般在调用链的最末端使用,区别在于是否可以获取前一个任务的返回值和自己是否返回值

方法名是否可获得前一个任务的返回值是否有返回值
thenApply能获得
thenAccept能获得
thenRun不可获得
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "this is before");
CompletableFuture<String> future2 = future1.thenApply(obj -> obj + ",this is after");
System.out.println(future2.get());// this is before,this is after

CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "this is before");
future3.thenAccept(System.out::println);// this is before

CompletableFuture<String> future4 = CompletableFuture.supplyAsync(() -> "this is before");
future4.thenRun(() -> {System.out.println("this is after");});// this is after

输出结果:

this is before,this is after
this is before
this is after

thenApply、thenAccept、thenRun 这三个方法都带有一个后缀为 Async 的方法

CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> {
    try {
        //TimeUnit.MILLISECONDS.sleep(1000);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "supplyAsync thread is " + Thread.currentThread().getName();
});
CompletableFuture<String> thenApply = supplyAsync.thenApply(obj -> obj + ",thenAccept thread is " + Thread.currentThread().getName());
CompletableFuture<String> thenApplyAsync = thenApply.thenApplyAsync(obj -> obj + ",thenApplyAsync thread is " + Thread.currentThread().getName());
System.out.println(thenApplyAsync.get());

三、thenCompose 和 thenCombine

1、thenCompose():当第一个任务完成时才会执行第二个操作。

CompletableFuture<String> thenCompose = CompletableFuture.supplyAsync(() -> "this is first")
                .thenCompose(obj -> CompletableFuture.supplyAsync(() -> obj + ",this is second"));
        System.out.println(thenCompose.get());

thenApply 也可以实现相似的功能,但是要 get() 两次。

CompletableFuture<CompletableFuture<String>> thenApply = CompletableFuture.supplyAsync(() -> "this is first")
                .thenApply(obj -> CompletableFuture.supplyAsync(() -> obj + ",this is second"));
        System.out.println(thenApply.get().get());

输出结果:

this is first,this is second

2、thenCombine():两个异步任务全部完成时才会执行某些操作。

CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> "this is first");
CompletableFuture<String> second = CompletableFuture.supplyAsync(() -> {
    try {
        TimeUnit.MILLISECONDS.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "this is second";
});
CompletableFuture<String> thenCombine = first.thenCombine(second, (s1, s2) -> s1 + "," + s2);
System.out.println(thenCombine.get());

输出结果:

this is first,this is second

四、allOf 和 join

CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> {
    System.out.println("first start");
    try {
        TimeUnit.MILLISECONDS.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("first return");
    return "this is first";
});
CompletableFuture<String> second = CompletableFuture.supplyAsync(() -> {
    System.out.println("second start");
    try {
        TimeUnit.MILLISECONDS.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("second return");
    return "this is second";
});
CompletableFuture<Void> allOf = CompletableFuture.allOf(first, second);
allOf.join();
System.out.println("all return");

输出结果:

first start
second start
second return
first return
all return

当线程 1 和线程2 都开始执行时,join 会带有阻塞功能,会在两条线程都执行完后才继续向下执行。

五、exceptionally 和 handle

1、exceptionally 处理异常,并且可以自定义返回值。

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    int i = 10 / 0;
    return i + "";
}).exceptionally(e -> {
    System.out.println("出现异常:" + e);
    return e.getMessage();
}).thenApply(obj -> "result is " + obj);
System.out.println(future.get());

输出结果:

出现异常:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
result is java.lang.ArithmeticException: / by zero

2、handle 同样是处理异常,并且可以自定义返回值。与 exceptionally 区别就是,handle 无论发没发生异常都会执行。另外就是 exceptionally 的自定义返回值类型必须与被处理的线程返回值一致,handle 不需要一致。

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    int i = 10 / 0;
    return i;
}).handle((result, e) -> {
    if (result == null) {
        System.out.println("出现异常:" + e);
        return e.getMessage();
    }
    return result;
}).thenApply(obj -> "result is " + obj);
System.out.println(future.get());

输出结果:

出现异常:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
result is java.lang.ArithmeticException: / by zero
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值