Java8——异步编程( 二 )


方法名是否可获得前一个任务的返回值是否有返回值thenApply能获得有thenAccept能获得无thenRun不可获得无
所以一般来说thenAccept、thenRun这两个方法在调用链的最末端使用 。接下来我们用真实的例子感受一下 。
//thenApply  可获取到前一个任务的返回值,也有返回值CompletableFuture<String> seqFutureOne = CompletableFuture.supplyAsync(()-> "seqFutureOne");CompletableFuture<String> seqFutureTwo = seqFutureOne.thenApply(name -> name + " seqFutureTwo");System.out.println(seqFutureTwo.get());//thenAccept  可获取到前一个任务的返回值,但是无返回值CompletableFuture<Void> thenAccept = seqFutureOne        .thenAccept(name -> System.out.println(name + "thenAccept"));System.out.println("-------------");System.out.println(thenAccept.get());//thenRun 获取不到前一个任务的返回值,也无返回值System.out.println("-------------");CompletableFuture<Void> thenRun = seqFutureOne.thenRun(() -> {    System.out.println("thenRun");});System.out.println(thenRun.get());返回的信息如下
seqFutureOne seqFutureTwoseqFutureOnethenAccept-------------null-------------thenRunnullthenApply和thenApplyAsync的区别我们可以发现这三个方法都带有一个后缀为Async的方法,例如thenApplyAsync 。那么带Async的方法和不带此后缀的方法有什么不同呢?我们就以thenApply和thenApplyAsync两个方法进行对比,其他的和这个一样的 。
这两个方法区别就在于谁去执行这个任务,如果使用thenApplyAsync,那么执行的线程是从ForkJoinPool.commonPool()中获取不同的线程进行执行,如果使用thenApply,如果supplyAsync方法执行速度特别快,那么thenApply任务就是主线程进行执行,如果执行特别慢的话就是和supplyAsync执行线程一样 。接下来我们通过例子来看一下,使用sleep方法来反应supplyAsync执行速度的快慢 。
//thenApply和thenApplyAsync的区别System.out.println("-------------");CompletableFuture<String> supplyAsyncWithSleep = CompletableFuture.supplyAsync(()->{    try {        Thread.sleep(10000);    } catch (InterruptedException e) {        e.printStackTrace();    }    return "supplyAsyncWithSleep Thread Id : " + Thread.currentThread();});CompletableFuture<String> thenApply = supplyAsyncWithSleep        .thenApply(name -> name + "------thenApply Thread Id : " + Thread.currentThread());CompletableFuture<String> thenApplyAsync = supplyAsyncWithSleep        .thenApplyAsync(name -> name + "------thenApplyAsync Thread Id : " + Thread.currentThread());System.out.println("Main Thread Id: "+ Thread.currentThread());System.out.println(thenApply.get());System.out.println(thenApplyAsync.get());System.out.println("-------------No Sleep");CompletableFuture<String> supplyAsyncNoSleep = CompletableFuture.supplyAsync(()->{    return "supplyAsyncNoSleep Thread Id : " + Thread.currentThread();});CompletableFuture<String> thenApplyNoSleep = supplyAsyncNoSleep        .thenApply(name -> name + "------thenApply Thread Id : " + Thread.currentThread());CompletableFuture<String> thenApplyAsyncNoSleep = supplyAsyncNoSleep        .thenApplyAsync(name -> name + "------thenApplyAsync Thread Id : " + Thread.currentThread());System.out.println("Main Thread Id: "+ Thread.currentThread());System.out.println(thenApplyNoSleep.get());System.out.println(thenApplyAsyncNoSleep.get());我们可以看到输出位
-------------Main Thread Id: Thread[main,5,main]supplyAsyncWithSleep Thread Id : Thread[ForkJoinPool.commonPool-worker-1,5,main]------thenApply Thread Id : Thread[ForkJoinPool.commonPool-worker-1,5,main]supplyAsyncWithSleep Thread Id : Thread[ForkJoinPool.commonPool-worker-1,5,main]------thenApplyAsync Thread Id : Thread[ForkJoinPool.commonPool-worker-1,5,main]-------------No SleepMain Thread Id: Thread[main,5,main]supplyAsyncNoSleep Thread Id : Thread[ForkJoinPool.commonPool-worker-2,5,main]------thenApply Thread Id : Thread[main,5,main]supplyAsyncNoSleep Thread Id : Thread[ForkJoinPool.commonPool-worker-2,5,main]------thenApplyAsync Thread Id : Thread[ForkJoinPool.commonPool-worker-2,5,main]


推荐阅读