起步
kotlin通过协程来实现异步操作,关于协程的一些基本概念可以参考这里<a target="_blank title=" null"="" style="word-wrap: break-word; color: rgb(59, 67, 72); word-break: break-all;">Kotlin中线程的代替者——协程,究竟有什么好?.
kotlin在它的标准库中仅仅提供了最小化的底层API的支持。像 async
和await
既不是Kotlin的关键字,又没有被包括在标准库中。
对于一般的开发者,或是刚入门的的人来说仅仅通过标准库提供的那些东西,要想使用其协程来是十分困难的。
幸运的是,我们不要从头写起,Kotlin官方已经为我们提供了轮子。kotlin.coroutines,这是一个十分丰富的库,它包含了大量的高层的开启协程的基本元素,包括前面提到的 async
和await
。
这个库是没有包含在标准库中,要想使用它必须导入相应的依赖。
Maven
<repository> <id>central</id> <url>http://jcenter.bintray.com</url></repository>
<dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-coroutines-core</artifactId> <version>0.18</version></dependency>
kotlin的版本需要1.1.4以上的版本(包括1.1.4)
<properties> <kotlin.version>1.1.4</kotlin.version></properties>
Gradle
repositories { jcenter() }
compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.18'
buildscript { ext.kotlin_version = '1.1.4'}
基础
接下来,开始编写你的第一段协程代码
fun main(args: Array<String>) { launch(CommonPool) { // 在一个公共线程池中创建一个协程 delay(1000L) // 非阻塞的延迟一秒(默认单位是毫秒) println("World!") // 在延迟后进行打印 } println("Hello,") // 主线程在协程延时后,不受影响,继续执行 Thread.sleep(2000L) // 阻塞主线程2秒钟,保持JVM存活}
输出结果:
Hello, World!
在这里协程通过名为launch的协程建造器进行启动。你可以把launch(CommonPool){...}换成 thread{...};delay() 换成 Thread.sleep()。 但是如果只是把launch换了,然后依旧使用delay()会产生怎样的结果呢?编译器会告诉你,发生了下面这样的错误:
Suspend functions are only allowed to be called from a coroutine or another suspend function
大意就是,挂起函数只允许在协程中或是另一个挂起函数中调用。而delay() 恰巧就是一个挂起函数,因此产生了这样的错误。
上个例子混合了阻塞和非阻塞的代码。那么我么怎么得到一个只有非阻塞操作的世界呢?这里我们就需要用到 run Blocking
fun main(args: Array<String>) = runBlocking<Unit> { // 开启主协程 launch(CommonPool) { // 在公共线程池中创建一个协程 delay(1000L) println("World!") } println("Hello,") // 主协程在子协程延迟时继续执行 delay(2000L) // 两秒钟的非阻塞延时,保持JVM存活}
假如主协程在子协程还没有执行之前就已经结束了,那么子协程也会随之结束。可是我们并不像让子协程结束,改怎么办呢?可以使用join()
让主协程等待子协程执行完成。
fun main(args: Array<String>) = runBlocking<Unit> { val job = launch(CommonPool) { // 创建一个协程并维持一个指向它任务的引用 delay(1000L) println("World!") } println("Hello,") job.join() // 持续等待,直到子协程执行完成}
接下来讲一下,这一次的最后一点内容:创建你的第一个挂起函数。
fun main(args: Array<String>) = runBlocking<Unit> { val job = launch(CommonPool) { doWorld() } println("Hello,") job.join() }// 这是你的第一个挂起函数suspend fun doWorld() { delay(1000L) println("World!") }
使用挂起函数有两点需要注意的地方
声明挂起函数需要添加 suspend 修饰符
挂起函数只能在协程中或是其它的挂起函数中使用。
共同学习,写下你的评论
评论加载中...
作者其他优质文章