美文网首页Android
Kotlin之协程(三)组合挂起函数

Kotlin之协程(三)组合挂起函数

作者: MakerGaoGao | 来源:发表于2021-09-17 09:03 被阅读0次

简介

介绍

此篇文章主要介绍了kotlin组合挂起函数,如果之前没有接触过协程,可以参考下面的文章目录

参考文档

  1. 谷歌开发者
  2. Kotlin文档

文章目录

Kotlin之协程(一)初识
Kotlin之协程(二)取消

简单组合挂起函数

1.顺序执行任务

代码如下:
   private fun test() = runBlocking {
        val time = measureTimeMillis {
            val str1 = doIt1()
            val str2 = doIt2()
            Log.d(Constants.TAG, "str1->${str1},str2->${str2}")
        }
        Log.d(Constants.TAG, "共计耗时:${time}ms")

    }


    suspend fun doIt1(): String {
        delay(1000)
        return "doIt1"
    }

    suspend fun doIt2(): String {
        delay(1000)
        return "dpIt2"
    }
日志如下:
2021-09-16 16:42:51.471 28858-28858/demo.demo.democoroutines D/Coroutines: str1->doIt1,str2->dpIt2
2021-09-16 16:42:51.471 28858-28858/demo.demo.democoroutines D/Coroutines: 共计耗时:2025ms
结果分析:

1、可以看到执行结果显示为2000+ms,是两个任务的顺序执行时长的叠加。

2.asyn进行异步并发执行

代码实现1如下:
private fun test() = runBlocking {
        val time = measureTimeMillis {
            val str1 = async { doIt1() }
            val str2 = doIt2()
            Log.d(Constants.TAG, "str1->${str1.await()},str2->${str2}")
        }
        Log.d(Constants.TAG, "共计耗时:${time}ms")

    }


    suspend fun doIt1(): String {
        delay(1000)
        return "doIt1"
    }

    suspend fun doIt2(): String {
        delay(1000)
        return "dpIt2"
    }
日志1如下:
2021-09-16 16:46:42.394 29253-29253/demo.demo.democoroutines D/Coroutines: str1->doIt1,str2->dpIt2
2021-09-16 16:46:42.394 29253-29253/demo.demo.democoroutines D/Coroutines: 共计耗时:1016ms
代码实现2如下:
 private fun test() = runBlocking {
        val time = measureTimeMillis {
            val str1 = async { doIt1() }
            val str2 = async { doIt2() }
            Log.d(Constants.TAG, "str1+str2->${str1.await()}+${str2.await()}")
        }
        Log.d(Constants.TAG, "共计耗时:${time}ms")

    }


    suspend fun doIt1(): String {
        delay(1000)
        return "doIt1"
    }

    suspend fun doIt2(): String {
        delay(1000)
        return "dpIt2"
    }
日志2如下:
2021-09-16 16:53:54.262 30702-30702/demo.demo.democoroutines D/Coroutines: str1+str2->doIt1+dpIt2
2021-09-16 16:53:54.263 30702-30702/demo.demo.democoroutines D/Coroutines: 共计耗时:1022ms
结果分析:

1、从耗时可以看出两个任务都进行了并行执行,方法1主要是将doIt1进行了异步,doIt2正常执行实现了并行,方法2是两个都进行了异步。
2、方法2注意最后显示的时候不能像方法1那样,不然await会导致占用,达不到理想效果(+和,隔开,"+"会同时异步执行","则会分开)。

3.Lazy模式的async

代码如下:
private fun test() = runBlocking {
        val time = measureTimeMillis {
            val str1 = async(start = CoroutineStart.LAZY) { doIt1() }
            val str2 = async(start = CoroutineStart.LAZY) { doIt2() }
            str1.start()
            str2.start()
            Log.d(Constants.TAG, "str1->${str1.await()},str2->${str2.await()}")
        }
        Log.d(Constants.TAG, "共计耗时:${time}ms")

    }


    suspend fun doIt1(): String {
        delay(1000)
        return "doIt1"
    }

    suspend fun doIt2(): String {
        delay(1000)
        return "dpIt2"
    }
日志如下:
2021-09-16 17:08:51.066 32123-32123/demo.demo.democoroutines D/Coroutines: str1->doIt1,str2->dpIt2
2021-09-16 17:08:51.066 32123-32123/demo.demo.democoroutines D/Coroutines: 共计耗时:1017ms
结果分析:

1、从耗时可以看出也实现了任务的并行执行。

4.asyn+coroutineScope实现结构化

代码1实现并发之并行:
 private fun test() = runBlocking {
        val time = measureTimeMillis {
            Log.d(Constants.TAG, "str->${doIt()}")
        }
        Log.d(Constants.TAG, "共计耗时:${time}ms")
    }


    suspend fun doIt(): String = coroutineScope {
        val str1 = async { doIt1() }
        val str2 = async { doIt2() }
        str1.await() + str2.await()
    }

    suspend fun doIt1(): String {
        delay(1000)
        throw RuntimeException("doIt1出现异常")
        return "doIt1"
    }

    suspend fun doIt2(): String {
        delay(1000)
        return "dpIt2"
    }
日志1如下:
2021-09-16 17:45:01.940 3312-3312/demo.demo.democoroutines D/Coroutines: str->doIt1dpIt2
2021-09-16 17:45:01.941 3312-3312/demo.demo.democoroutines D/Coroutines: 共计耗时:1022ms
结果1分析:

1、由耗时可以看出两个任务也是一起进行执行的

代码2实现结构化并发之取消:

 private fun test() = runBlocking {
        val time = measureTimeMillis {
            try {
                val str = doIt()
                Log.d(Constants.TAG, "str->${str}")
            } catch (e: Exception) {
                Log.d(Constants.TAG,"doIt出现异常:$e")
            } finally {
                Log.d(Constants.TAG,"doIt-finally")
            }
        }
        Log.d(Constants.TAG, "共计耗时:${time}ms")
    }


    suspend fun doIt(): String = coroutineScope {
        val str1 = async { doIt1() }
        val str2 = async { doIt2() }
        str1.await() + str2.await()
    }

    suspend fun doIt1(): String {
        delay(1000)
        throw RuntimeException("doIt1-执行出现异常")
    }

    suspend fun doIt2(): String {
        try {
            delay(2000)
        } catch (e: Exception) {
            Log.d(Constants.TAG, "doIt2:$e")
        } finally {
            Log.d(Constants.TAG, "doIt2-finally")
        }
        return "dpIt2"
    }
日志2如下:
2021-09-16 17:52:49.923 4299-4299/demo.demo.democoroutines D/Coroutines: doIt2:kotlinx.coroutines.JobCancellationException: Parent job is Cancelling; job=ScopeCoroutine{Cancelling}@613f107
2021-09-16 17:52:49.923 4299-4299/demo.demo.democoroutines D/Coroutines: doIt2-finally
2021-09-16 17:52:49.924 4299-4299/demo.demo.democoroutines D/Coroutines: doIt出现异常:java.lang.RuntimeException: doIt1-执行出现异常
2021-09-16 17:52:49.924 4299-4299/demo.demo.democoroutines D/Coroutines: doIt-finally
2021-09-16 17:52:49.924 4299-4299/demo.demo.democoroutines D/Coroutines: 共计耗时:1028ms
结果2分析:

1、从耗时可以看出,两个任务在并行执行,并且在doIt1出现异常之后整个doIt任务结束。
2、执行顺序首先是在doIt1异常之后,doIt2被取消,其次doIt打印出的异常为doIt1传递出的异常。

总结

本问主要介绍了组合函数的挂起及异步执行,同时介绍了结构化并发的实现以及其取消与异常传递,当然这也是本人的学习笔记,希望也能对大家有那么一点点的帮助或者启发,我就很开心了。当然了本人也是在学习与理解的过程中记录与理解难免有一定的认知局限性,如果发现有什么问题,欢迎指正,谢谢。

相关文章

网友评论

    本文标题:Kotlin之协程(三)组合挂起函数

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