对于Kotlin中的协程有什么理解?
每次看到这个问题的时候,看到官方的回答大多数基本是都是这样的:协程视为一种轻量级线程,可用于提高并发代码的性能。这样的一句解释,看到是不是一头雾水。 首先,我们可以先尝试着理解下Kotlin官网说的这段话
可以将协程视为一种轻量级线程。和线程一样,协程可以并行运行,相互等待和通信。最大的区别是协程非常便宜,几乎是免费的:我们可以创建成千上万个协程,并且在性能方面支付的费用很少。另一方面,真正的线程的启动和维护成本很高。一千个线程对于现代机器来说可能是一个严峻的挑战。
其实这个回答对笔者来说是挺抽象的,不是特别好理解,所以就重新梳理下,首先我们从协程的英文名词来拆解下
Coroutines = Co + Rountines
这里_Co_指的是合作,而Routines代表的是电脑执行的一些例行程式,什么意思呢?就是意味着当这些函数程式相互协作的时候,我们就称之为协程。
通过上面这张图,笔者用一个例子来方便自己理解,为了更直观的感受协程的魅力,这里使用了_when_关键字进行辅助。假设有两个函数它们分别是_functionA_和_functionB_
_functionA_如下代码所示:
fun functionA(case: Int) { when (case) { 1 -> { taskA1() functionB(1) } 2 -> { taskA2() functionB(2) } 3 -> { taskA3() functionB(3) } 4 -> { taskA4() functionB(4) } }}_functionB_如下代码所示:
fun functionB(case: Int) { when (case) { 1 -> { taskB1() functionA(2) } 2 -> { taskB2() functionA(3) } 3 -> { taskB3() functionA(4) } 4 -> { taskB4() } }}然后,我们调用_functionA_,此时会发生什么事呢?
functionA(1)在这里,functionA_将执行_taskA1 并交给functionB控制执行_taskB1_;然后,_functionB_将执行taskB1并将控制权交还给_functionA_执行_taskA2_等等,如此类推下去,重要的是,functionA_与_functionB_彼此合作。 现在我们使用Kotlin协程就可以非常轻松地完成上述工作,而无需使用例子所示的_when, 只是方便自己理解。现在,我们可以暂时的理解为协程就是函数之间的相互协作,由于这些功能的协作性质,存在着无限的可能性。
- 它可以执行几行 functionA,然后执行几行 functionB,然后再执行几行 functionA,依此类推。当一个线程处于空闲状态并且什么都不做时,这将很有帮助,在这种情况下,它可以执行另一个函数的几行。这样,它就可以充分利用线程,有助于多任务处理
- 支持以同步的方式编写异步代码总而言之,协程让多任务处理变得非常简单,可以说协程和线程都是多任务的,但不同的是,线程由操作系统管理,协程由用户管理,因为它拥有可以利用协作执行几行代码的功能。简单来说,协程就是一个基于实际编写的优化框架,利用函数的协作特性使其轻巧而强大。所以,我们总是说协程是一个轻量级的线程,这也意味着,它不映射到本机线程,因此不需要在处理器上进行上下文切换,因此协程速度更快。可能有些同学已经注意到上面我所说的,”不映射到本机线程“,这是什么意思呢?一般来说,基本上有两种类型的协程
- 无堆叠
- 堆积如山的而Kotlin实现的是无堆栈的协程,说明协程没有自己的堆栈,因此它们不会映射到本机线程。现在,我们反过头来理解Kotlin官网说的定义,才真正明白,协程并没有取代线程,它其实更像是一个框架来管理着它们。
综上所述,笔者对协程(Coroutines)有了更加确切的理解:它是一种更高效和更简单的方式管理并发的框架,其轻量级线程编写在实际线程框架之上,通过利用函数的协作性质来充分利用它。