Kotlin协程简介
Kotlin, as a language, provides only minimal low-level APIs in its standard library to enable various other libraries to utilize coroutines. Unlike many other languages with similar capabilities, async
and await
are not keywords in Kotlin and are not even part of its standard library. Moreover, Kotlin's concept of suspending function provides a safer and less error-prone abstraction for asynchronous operations than futures and promises.
kotlinx.coroutines
is a rich library for coroutines developed by JetBrains. It contains a number of high-level coroutine-enabled primitives that this guide covers, including launch
, async
and others.
This is a guide on core features of kotlinx.coroutines
with a series of examples, divided up into different topics.
In order to use coroutines as well as follow the examples in this guide, you need to add a dependency on kotlinx-coroutines-core
module.
[ https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html ]
协程是一个轻量级的线程。
Kotlin 中的协程的实现原理是: coroutine == continuation + coroutine scope.(关于这个continuation 和 coroutine scope 我们会在后面的文章中介绍.)
想要使用 Kotlin 协程,需要单独添加依赖:
compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.2.2'
先用一个官方的demo,直观认识一下协程:
import kotlinx.coroutines.*
fun main() {
GlobalScope.launch { // launch a new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay
}
println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}
输出:
Hello, World!
Kotlin帮我们去完成线程的调度。
而这里GlobalScope.launch就是创建一个协程环境并且启动一个协程。
协程上下文包括了一个 协程调度器,它确定了相应的协程在执行时使用一个或多个线程。协程调度器可以将协程的执行局限在指定的线程中,调度它运行在线程池中或让它不受限的运行。
其中, GlobalScope 继承了 CoroutineScope:
* A global [CoroutineScope] not bound to any job.
*
* Global scope is used to launch top-level coroutines which are operating on the whole application lifetime
* and are not cancelled prematurely.
* Another use of the global scope is operators running in [Dispatchers.Unconfined], which don't have any job associated with them.
*
* Application code usually should use an application-defined [CoroutineScope]. Using
* [async][CoroutineScope.async] or [launch][CoroutineScope.launch]
* on the instance of [GlobalScope] is highly discouraged.
我们再写一个稍微丰富一点的例子:
package com.kotlin.notes.coroutine
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.lang.Thread.sleep
class CoroutineDemo {
fun doSomething() {
for (i in 0..5) {
println(i)
sleep(1000)
}
println("doSomething done")
}
suspend fun suspendDoSomething() {
for (i in 0..5) {
println(i)
delay(1000)
}
}
}
fun main() = runBlocking {
val d = CoroutineDemo()
d.doSomething()
val job = GlobalScope.launch {
d.suspendDoSomething()
}
println("suspendDoSomething done?")
job.join()
println("suspendDoSomething done!")
}
输出:
0
1
2
3
4
5
doSomething done
suspendDoSomething done?
0
1
2
3
4
5
suspendDoSomething done!
Composing suspending functions
下面我们再看一下 suspend 函数的组合调用.
定义两个suspend函数如下:
suspend fun doSomethingA(): Int {
delay(1000L) // pretend we are doing something useful here
return 10
}
suspend fun doSomethingB(): Int {
delay(1000L) // pretend we are doing something useful here, too
return 10
}
然后,我们调用上面的函数:
val d = CoroutineDemo()
val time = measureTimeMillis {
val a = d.doSomethingA()
val b = d.doSomethingB()
println("The answer is ${a + b}")
}
println("Completed in $time ms")
运行输出:
The answer is 20
Completed in 2026 ms
上面的方式是同步的方式. 下面我们在来看一下异步执行的方式:
val time = measureTimeMillis {
val a = async { d.doSomethingA() }
val b = async { d.doSomethingB() }
println("The answer is ${a.await() + b.await()}")
}
println("Completed in $time ms")
运行输出:
The answer is 20
Completed in 1042 ms
这里的 async 需要运行在一个协程环境之中,所以我们这里用了一个GlobalScope.launch。
async会返回一个Deferred对象,在async方法结束的时候,就会调用await()方法。因此,我们可以通过await()就可以得到异步回调。有了这个特性,我们网络请求的时候就会非常的方便。
[ref:https://kotlinlang.org/docs/reference/coroutines/composing-suspending-functions.html]
本文代码实例源码地址:
https://gitee.com/universsky/kotlin-notes
Kotlin 开发者社区
国内第一Kotlin 开发者社区公众号,主要分享、交流 Kotlin 编程语言、Spring Boot、Android、React.js/Node.js、函数式编程、编程思想等相关主题。
标签:协程,Kotlin,编程,kotlinx,coroutines,println,async From: https://blog.51cto.com/u_15236724/5946918