CompletableFuture

CompletableFuture

简介

扩展 Future 功能,通过 CompletionStage 提供函数式编程的能力,简化异步编程

基本用法

  • CompletableFuture ,实现了 Future<T>, CompletionStage<T> 两个接口。
  • Executor 参数可以手动指定线程池,否则默认 ForkJoinPool.commonPool() 系统级公共线程池。这些线程都是守护线程,主线程结束守护线程不结束,只有JVM关闭时,生命周期终止。
  • 以 Async 结尾的方法都是异步执行,即到线程池取个新线程执行

创建

  • supplyAsync
    创建有返回值的任务 参数 Supplier
  • runAsync
    建没有返回值的任务 参数 Runnable
  • completedFuture
    创建已完成的任务 参数为值

消费

  • whenComplete whenCompleteAsync
    消费任务结果 参数 BiConsumer
  • exceptionally
    消费任务异常 参数 Function
  • handle handleAsync
    消费任务结果和异常 参数 BiFunction

变换

  • thenApply thenApplyAsync
    有入参有返回值 参数 Function

  • thenAccept thenAcceptAsync
    有入参无返回值 参数 Consumer

  • thenRun thenRunAsync
    无入参无返回值 参数 Runnable

  • thenCompose thenComposeAsync
    构成新任务 参数 Function

组合

  • thenCombine thenCombineAsync
    双线有入参有返回值 参数 CompletionStage BiFunction

  • thenAcceptBoth thenAcceptBothAsync
    双线有入参无返回值 参数 CompletionStage BiConsumer

  • runAfterBoth runAfterBothAsync
    双线无入参无返回值 参数 CompletionStage Runnable

  • applyToEither applyToEitherAsync
    二选快有入参有返回值 参数 CompletionStage Function

  • acceptEither acceptEitherAsync
    二选快有入参无返回值 参数 CompletionStage Consumer

  • runAfterEither runAfterEitherAsync
    二选快无入参无返回值 参数 CompletionStage Runnable

群体

  • anyOf
    只要有完成即触发有返回值 参数 CompletableFuture...
  • allOf
    全部完成才触发无返回值,可接收异常 参数 CompletableFuture...
fun testAnyOfAndAllOf() {
    val f1: CompletableFuture<String> = CompletableFuture.supplyAsync {
        TimeUnit.SECONDS.sleep(2)
        return@supplyAsync Thread.currentThread().name
    }.whenComplete { t, u ->
        println("t1: ${System.currentTimeMillis()}: ${Thread.currentThread().name}: $t $u")
    }

    val f2: CompletableFuture<String> = CompletableFuture.supplyAsync {
        TimeUnit.SECONDS.sleep(1)
        return@supplyAsync Thread.currentThread().name
    }.whenCompleteAsync { t, u ->
        println("t2: ${System.currentTimeMillis()}: ${Thread.currentThread().name}: $t $u")
    }

    CompletableFuture.anyOf(f1, f2)
        .whenComplete { t, u ->
            println("anyOf: ${System.currentTimeMillis()}: ${Thread.currentThread().name}: $t $u")
        }

    CompletableFuture.allOf(f1, f2)
        .whenComplete { t, u ->
            println("allOf: ${System.currentTimeMillis()}: ${Thread.currentThread().name}: $t $u")
        }.join()
}
t2: 1550851312825: ForkJoinPool.commonPool-worker-2: ForkJoinPool.commonPool-worker-2 null
anyOf: 1550851312825: ForkJoinPool.commonPool-worker-2: ForkJoinPool.commonPool-worker-2 null
t1: 1550851313822: ForkJoinPool.commonPool-worker-1: ForkJoinPool.commonPool-worker-1 null
allOf: 1550851313822: ForkJoinPool.commonPool-worker-1: null null

完成

  • complete completeExceptionally cancel
    触发完成
  • isDone isCompletedExceptionally isCancelled
    判断任务是否已经结束

获取结果

  • get
    阻塞等待,获取任务结果,会抛出 ExecutionException InterruptedException CancellationException
  • join
    阻塞等待,获取任务结果,异常 CompletionException CancellationException
  • getNow
    立即取到结果,任务未结束则返回传入参数,异常 CompletionException CancellationException

切换线程

使用 Executor 切换执行任务线程,例如在 Android 中在主线程和子线程切换

fun testExecutor() {
    CompletableFuture.supplyAsync(Supplier {
        TimeUnit.SECONDS.sleep(2)
        println("t1: ${Thread.currentThread().name}") // t1: pool-1-thread-1
        return@Supplier "t1"
    }, AppExecutors.io).thenApplyAsync(Function<String, String> {
        println("t2: ${Thread.currentThread().name}") // t2: main
        return@Function "$it.t2"
    }, AppExecutors.main).thenApplyAsync(Function<String, String> {
        println("t3: ${Thread.currentThread().name}") // t3: pool-2-thread-1
        return@Function "$it.t3"
    }, AppExecutors.single).whenCompleteAsync(BiConsumer { t, u ->
        println("t4: ${Thread.currentThread().name}: $t $u") // t4: main: t1.t2.t3 null
    }, AppExecutors.main)
}

object AppExecutors {
    val io: ExecutorService by lazy {
        Executors.newCachedThreadPool()
    }

    val compute: ExecutorService by lazy {
        val threadCount = 3
        Executors.newFixedThreadPool(threadCount)
    }

    val single: ExecutorService by lazy {
        Executors.newSingleThreadExecutor()
    }

    val main: Executor by lazy {
        MainThreadExecutor()
    }

    private class MainThreadExecutor : Executor {
        private val mainThreadHandler: Handler = Handler(Looper.getMainLooper())

        override fun execute(command: Runnable?) {
            mainThreadHandler.post(command);
        }
    }
}

参考

CompletableFuture
Java8新特性整理之CompletableFuture:组合式、异步编程(七)
CompletableFuture 使用详解
个人愚见:分布式框架中使用CompletableFuture提高效率
Java并发编程系列一:Future和CompletableFuture解析与使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值