Kotlin Coroutine 协程

1 什么是 协程

Coroutine 被翻译成了“协程”,意思就是要各个子任务程协作运行的意思,所以大家一下就明白了它被创造出来是要解决异步问题的。

我们写 Java 的程序员,对线程更熟悉一些。线程是比进程更小一级的运行单位,它的调度由操作系统来完成,所以我们只管 new Thread 和 start,至于什么时候 run,什么时候 run 完,我们都没办法预见。

Thread t =newThread(task);  t.start();

尽管有诸多不可控的因素,不过我们可以肯定的是起了一个新的线程并启动它之后,当前线程并不会受到阻塞。如果大家再往深处想想,CPU 在任意时刻运行什么进程及其线程,是操作系统决定的,但归根结底一个单线程的 CPU 在任一时刻只能运行一个任务。

那么协程呢?协程的调度是应用层完成的。这个调度与线程调度有着比较大的差别,线程调度是抢占式调度,很有可能线程 A 运行得美滋滋的,线程 B 突然把 CPU 抢过来,跟 A 说“你给我下去吧你”,于是线程 A 只能干瞪眼没办法;而协程的调度是非抢占式的,目前常见的各支持协程的语言实现中都有 yield 关键字,它有“妥协、退让”的意思,如果一个协程执行到一段代码需要歇会儿,那么它将把执行权让出来,如果它不这么做,没人跟它抢。

2 Kotlin 协程初体验

Kotlin 1.1 对协程的基本支持都在 Kotlin 标准库当中,主要涉及两个类和几个包级函数和扩展方法:

CoroutineContext:协程的上下文,这个上下文可以是多个的组合,组合的上下文可以通过 key 来获取。EmptyCoroutineContext 是一个空实现,没有任何功能,如果我们在使用协程时不需要上下文,那么我们就用这个对象作为一个占位即可。上下文这个东西,不管大家做什么应用,总是能遇到,比如 Android 里面的 Context,JSP 里面的 PageContext 等等,他们扮演的角色都大同小异:资源管理,数据持有等等,协程的上下文也基本上是如此。


Continuation:顾名思义,继续、持续的意思。我们前面说过,协程提供了一种暂停的能力,可继续执行才是最终的目的,Continuation 有两个方法,一个是 resume,如果我们的程序没有任何异常,那么直接调用这个方法并传入需要返回的值;另一个是 resumeWithException,如果我们的程序出了异常,那我们可以通过调用这个方法把异常传递出去

Kotlin Coroutine 协程_第1张图片

协程的基本操作,包括创建、启动、暂停和继续,继续的操作在 Continuation 当中,剩下的三个都是包级函数或扩展方法:

Kotlin 还增加了一个关键字:suspend,用作修饰会被暂停的函数,被标记为 suspend 的函数只能运行在协程或者其他 suspend 函数当中。


让我们来看一个例子:

Kotlin Coroutine 协程_第2张图片
Kotlin Coroutine 协程_第3张图片

这段程序在模拟计算文件的 Md5 值。我们知道,文件的 Md5 值计算是一项耗时操作,所以我们希望启动一个协程来处理这个耗时任务,并在任务运行结束时打印出来计算的结果。

运行结果:

Kotlin Coroutine 协程_第4张图片

你可能感兴趣的:(Kotlin Coroutine 协程)