美文网首页
Kotlin协程 async 和 withContext

Kotlin协程 async 和 withContext

作者: thishejue | 来源:发表于2024-02-27 16:31 被阅读0次

async和withContext都可以返回耗时任务的执行结果。

  • 多个 async 任务是并行的,async 返回的是一个Deferred<T>,需要调用await()方法获取结果。
  • 多个 withContext 任务是串行的, 且withContext 可直接返回耗时任务的结果。

例1

先来看下在协程内,用普通的方式,计算两数之和,并统计所需时间。

   fun test() = runBlocking {

        val time = measureTimeMillis {
            val ds1 = doSomething1()
            val ds2 = doSomething2()
            println("The result is ${ds1 + ds2}")
        }

        println("time is $time ms")
    }

    suspend fun doSomething1(): Int {
        delay(1000)
        return 5
    }

    suspend fun doSomething2(): Int {
        delay(1000)
        return 6
    }

输出:

The result is 11
time is 2019 ms

分析:
因为doSomething1()和doSomething2()是顺序进行,所有时间为2019ms,接近2000ms。

例2

现在,使用async和await,再来看下。

    fun test() = runBlocking {

        val time = measureTimeMillis {
            val ds1 = async { doSomething1() }
            val ds2 = async { doSomething2() }
            val r1 = ds1.await()
            val r2 = ds2.await()
            println("The result is ${r1 + r2}")
        }

        println("time is $time ms")
    }

    suspend fun doSomething1(): Int {
        delay(1000)
        return 5
    }

    suspend fun doSomething2(): Int {
        delay(1000)
        return 6
    }

输出:

The result is 11
time is 1027 ms

分析:
计算结果仍然正确,但所需时间只要约1000ms。可见两者是并发的。所以,async是类似launch的,可以实现并发的执行任务,但是launch不会返回结果。

例3

在加上CoroutineStart启动方式(CoroutineStart.LAZY)

    fun test() = runBlocking {

        val time = measureTimeMillis {
            val ds1 = async(start = CoroutineStart.LAZY) { doSomething1() }
            val ds2 = async(start = CoroutineStart.LAZY) { doSomething2() }

            // 如果立即都start了,那结果(时间消化)类似例2
//            ds1.start()
//            ds2.start() 

            // 如果之前没有start,那会等到调用await时候才启动,这样又类似顺序执行了
            val r1 = ds1.await()
            val r2 = ds2.await()
            println("The result is ${r1 + r2}")
        }

        println("time is $time ms")
    }

输出:

The result is 11
time is 2018 ms

分析:
在CoroutineStart.LAZY启动方式下,async会等到start或者await才启动。如上,之前如果没有start,那只有等到await,才启动,并且遇到第一个await便会阻塞。因此,所需的时间便是两者之和。

例4

现在使用withContext

fun test() = runBlocking {

        val time = measureTimeMillis {

            val r1 = withContext(Dispatchers.IO) {
                println("at withContext1: ${getCurrentThread()}")
                delay(1000)
                5
            }

            val r2 = withContext(Dispatchers.IO) {
                println("at withContext2: ${getCurrentThread()}")
                delay(1000)
                6
            }

            println("The result is ${r1 + r2}")
        }

        println("time is $time ms")
    }

输出:

at withContext1: DefaultDispatcher-worker-1
at withContext2: DefaultDispatcher-worker-1
The result is 11
time is 2034 ms

分析:
可以看出两者是顺序执行的,耗时时间接近2000ms

相关文章

网友评论

      本文标题:Kotlin协程 async 和 withContext

      本文链接:https://www.haomeiwen.com/subject/efatzdtx.html