协程是什么现象?这些基本上是轻量级线程,可以更好地使用它们正在运行的应用程序。此外,无需手动控制执行它们的线程。
开发人员远离线程的生命周期,因为协程添加的新抽象确保了任务之间的上下文切换。从而更合理地利用线程的运行时间。
从臭名昭著的缓慢输入/输出任务中最终获得结果并不需要很长时间。相反,它继续处理其他协程发出的任务。
开发人员的典型工作日涉及代码构建,每个大约需要 3-5 分钟。与此同时,他们检查电子邮件和推特,做一些伸展运动,或者简单地放松一下,随便你说。这就是协程介入的地方。您可以在等待构建完成时充分利用您的时间。
展望未来,Kotlin 协程的想法并不是全新的。许多编程语言都使用它们,例如 Go(goroutines)、Erlang 和 Java(Project Loom)。
安装阶段
只有少数关键字与 Kotlin 库集成。这没什么大不了的。您只需添加一个依赖项kotlinx-coroutines-core
即可进入协程。那不会花太多力气。自己检查一下。
Gradle:
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
Maven:
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
只要库得到更新,变化就会改变。
一个简单的协程
让我们考虑下面的一个有限范围的例子来熟悉协程。请记住,这种模式没有显示出大多数的好处。你对协程了解得越多,你就越能意识到它们的好处。
首先,检查一下:
fun main() = runBlocking {
launch {
delay(2000)
println("and it worked for me!")
}
print("My first coroutine, ")
}
delay
在进行下一步之前,代码会使用 a 激活协程- 打印出来。简洁的示例包含几个功能来吸引您的注意力。仔细看看他们。
runBlocking
– 运行一个新的协程,阻塞正在进行的线程直到它完成。换句话说,运行它的线程在调用期间被阻塞,直到里面的所有协程完成它们的执行。此处的模式仅说明示例。launch
– 是所谓的协程构建器。它在不阻塞当前线程的情况下启动一个新的协程。另外,从现在launch
继承。CoroutineContext
CoroutineScope
delay
– 暂停协程一段时间。它会暂时停止协程的持续Thread.sleep
存在。但与该方法不同的是,底层线程不会被阻塞。或者,协程暂停。它释放其线程以启用另一个协程执行。一个线程在结束时可以获得delay
,并且协程从它停止的地方继续。
澄清条款
有几句话要解释。
- 暂停协程。协程共享线程,比方说,来自各自的池。这是一个可以在以后暂停和恢复的功能。他们执行一个长时间的操作并等待它完成而不阻塞。这正是协程的优势:实际运行的协程在数量上明显优于可用线程。
CoroutineContext
– 标记元素/元素集的界面。它确定协程运行的上下文。CoroutineScope
– 指定用于跟踪其生命周期的新协程的范围。它由CoroutineContext
最近在其中激活的协程组成。具体来说,CoroutineScope
产生新协程的扩展函数。从示例中可以看出,runBlocking
正在将其渲染CoroutineScope
到对launch
.
暂停功能
那是什么样的功能?
这样的方法已经在上面的例子中展示过—— delay
。的组成为delay
:
public suspend fun delay(timeMillis: Long) {
if (timeMillis <= 0) return // don't delay
return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont)
}
}
幸运的是,Kotlin 语言包含suspend
关键字。它有什么意义?
您知道在某个点执行暂停的函数被标记为suspend
。老实说,需要彻底了解细节才能对此事提供全面的解释。否则,弄清楚函数何时暂停可能真的很纠结。
你什么时候用 注释函数suspend
?如果函数以 . 开头suspend
,并且调用点在协程之外,请按照书本行事。
比较协程外的调用点:
suspend fun printAfterDelay() {
delay(2000)
println("and it work!")
}
另一方面,到协程内的调用点:
fun CoroutineScope.printAfterDelay() = launch {
delay(2000)
println("and it work!")
}
顺便说一句,您是否注意到这两个示例都是对原始示例的微不足道的代码重构?
编译器将在各种情况下派上用场,这正是关键字的好处。因此,编译以下内容:
fun printAfterDelay() {
delay(2000)
println("and it work!")
}
最终会导致这样的错误:
Suspend function 'delay' should be called only from a coroutine or
another suspend function
请注意,这是在您从技术上采取行动并成为编码专家之前的指导性解释。
概括
Kotlin 协程被认为是轻量级线程,这是一种提供程序多线程的方法,因为它们可以在操作系统不使用上下文切换机制的情况下实现。
当某个协程遇到暂停点时,它们会拆分并输出其底层资源。这可以有效地使用应用程序资源,因为在长期任务期间不必阻塞线程。
最后,我们看了一下简单的协程和挂起函数的简单模式。最后,我们谈到了suspend
关键字以及如何操作它。
给定的示例并未说明使用协程的真正价值。本文仅介绍基础知识。请留意有关该主题的进一步深入指导。