Kotlin回顾9.协程思维模型

Posted bug樱樱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin回顾9.协程思维模型相关的知识,希望对你有一定的参考价值。

1.协程

协程不是进程或线程,它的执行过程更类似于子例程或者说不带返回值的函数调用。

一个程序可以包含多个协程,类似于一个进程包含多个线程。线程有自己的上下文多个线程存在时它们相对独立,切换受系统控制,而协程也相对独立,也有自己的上下文,但是切换是由自己控制的,当需要切换到其他协程时是由当前协程控制的。

线程协程
独立性相对独立相对独立
上下文有自己的上下文有自己的上下文
切换系统决定是否切换当前协程决定是否切换

2.Kotlin协程

1.引入Kotlin协程

Kotlin中如果要使用协程是需要添加依赖的,它没有被集成在标准库中,单独拎出来主要是为了减小标准库的体积

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'

那么要如何理解Kotlin协程?Kotlin协程可以理解为更轻量级的线程,协程的运行离不开线程,这有点像线程和进程之间的关系。

2.Kotlin协程的使用

fun main() = runBlocking 
    doWorld()


suspend fun doWorld() = coroutineScope   
    launch 
        delay(1000L)
        println("World!")
    
    println("Hello")


//输出结果:
//Hello
//World!

上面的代码是Kotlin协程的一个简单例子其中runBlockingcoroutineScopelaunch是协程作用域,suspend是挂起,delay(1000L)是一个延时函数。从结果来看我们的代码顺序和输出结果的顺序不一样,这就是Kotlin协程的魅力,我们看下面的流程图:

3.Kotlin协程的轻量(总结的还不够清晰)

  • 启动 10 亿个线程,这样的代码运行在大部分的机器上都是会因为内存不足等原因而异常退出的。那么启动10亿个协程则不会出现异常因为协程是非常轻量的;

  • 协程虽然是运行在线程上的但是它并不会与某个线程绑定,而且还可以在不同线程之间切换。

4.协程的“非阻塞式”

线程是阻塞的,因为它在运行一个耗时任务时只有这个任务完成了才会执行后面的任务,而Kotlin在执行一个耗时任务时会把这个任务放入后台执行,去执行下一个任务。

fun main() 
    repeat(3) 
        Thread.sleep(1000L)
        println("Print-1:$Thread.currentThread().name")
    

    repeat(3) 
        Thread.sleep(900L)
        println("Print-2:$Thread.currentThread().name")
    


/*
输出结果:
Print-1:main
Print-1:main
Print-1:main
Print-2:main
Print-2:main
Print-2:main
*/

上面的代码是阻塞式任务,可以看到两个任务之间的等待时差是100毫秒,但是第二个repeat执行的前提是第一个repeat执行完毕,那么这个任务的最终耗时就是5700毫秒。

fun main() = runBlocking 
    launch 
        repeat(3) 
            delay(1000L)
            println("Print-1:$Thread.currentThread().name")
        
    

    launch 
        repeat(3) 
            delay(900L)
            println("Print-2:$Thread.currentThread().name")
        
    
    delay(3000L)


/*
输出结果:
Print-2:main @coroutine#3
Print-1:main @coroutine#2
Print-2:main @coroutine#3
Print-1:main @coroutine#2
Print-2:main @coroutine#3
Print-1:main @coroutine#2
*/

上面的代码是非阻塞式任务,可以看到两个任务之间的等待时差是100毫秒,第以个repeat和第二个repeat是同时执行的,也就是说他们同时开始执行,当达到900毫秒时第二个repeat开始执行,当达到1000毫秒时第一个repeat开始执行,那么这个任务的最终耗时就是3000毫秒。

由此可见,Kotlin 协程的“非阻塞”其实只是语言层面的,当我们调用 JVM 层面的 Thread.sleep() 的时候,它仍然会变成阻塞式的。与此同时,这也意味着我们在协程当中应该尽量避免出现阻塞式的行为。尽量使用 delay,而不是 sleep。

到这里其实就会产生一个疑问,delay就能解决阻塞的问题吗?答案是不是,解决阻塞问题的其实是Kotlin的挂起和恢复的能力,这是协程才拥有的特殊能力。

挂起和恢复又该怎么理解呢,举个例子,现在有两件事情:①烧一壶水烧开后断开电源;②做饭;第一件事是一个耗时任务,开始烧水后我去做第二件事这就是挂起,当水烧开以后要去断开电源这就是恢复。

5.建立思维模型

Kotlin的协程要比Java线程更抽象,因为Java的线程可以找到Thread的源码,同时线程也是操作系统中的一个概念,所以理解起来较为简单。而Kotlin的协程没有类似的知识点可以建立关联,所以在学习Kotlin协程的时候就需要简历协程的思维模型, 没有这个思维理解Kotlin协程就比较难。

如何建立Kotlin的思维模型?可以将Kotlin协程想象成一个“更加轻量级的线程”。

从包含关系上看,协程跟线程的关系,有点像线程与进程的关系,毕竟协程不可能脱离线程运行。所以,协程可以理解为运行在线程当中的、更加轻量的 Task

作者:无糖可乐爱好者
链接:https://juejin.cn/post/7171677203384500238

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。

相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

二、源码解析合集


三、开源框架合集


欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

以上是关于Kotlin回顾9.协程思维模型的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin回顾25.Kotlin协程—select

android kotlin 协程 协程间的通信

android kotlin 协程 协程间的通信

使用实时数据,协程(Kotlin)测试视图模型

Kotlin协程

Kotlin协程