Kotlin学习教程之协程Coroutine

定义

Coroutine翻译为协程,Google翻译为协同程序,一般也称为轻量级线程,但需要注意的是线程是操作系统里的定义概念,而协程是程序语言实现的一套异步处理的方法。

在Kotlin文档中,Coroutine定义为一个可被挂起的计算实例,下面话不多说了,来一起看看详细的介绍吧。

配置

build.gradle中dependencies 添加下面2行,注意coroutine目前仍处于experiment阶段,但Kotline官方保证向前兼容。

 dependencies {
  implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5'
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.19.3"
 }

实例

我们看一个简单Android示例:

activity_coroutine.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".coroutine.CoroutineActivity">

 <TextView
  android:id="@+id/tvHello"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>

CoroutineActivity.kt

class CoroutineActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_coroutine)
  setup()
 }

 fun setup() {
  launch(UI) { // launch coroutine in UI context
   for (i in 10 downTo 1) { // countdown from 10 to 1
    tvHello.text = "Countdown $i ..." // update text
    delay(1000) // wait half a second
   }
   tvHello.text = "Done!"
  }
 }
}

运行程序 tvHello从10倒计时显示到1,最后显示"Done!"

代码分析:

我们重点分析setup()函数

  • launch(UI) {...} -----在UIcontext下启动coroutine
  • delay(1000) ----将当前coroutine挂起1秒

看到这里你可能会疑惑,Android开发中不是禁止在主线程下做延迟或者阻塞操作吗?

我们回顾下Coroutine的定义:一个可被挂起的计算实例。

Coroutine不是线程,所以挂起Coroutine不会影响当前线程的运行。

取消Coroutine运行

我们修改下上面的代码:

class CoroutineActivity : AppCompatActivity() {
 lateinit var job:Job
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_coroutine)
  setup()
 }

 fun setup() {
  job = launch(CommonPool) { // launch coroutine in UI context
   for (i in 10 downTo 1) { // countdown from 10 to 1
    tvHello.text = "Countdown $i ..." // update text
    delay(1000) // wait half a second
   }
   tvHello.text = "Done!"
  }
 }

 override fun onPause() {
  super.onPause()
  job.cancel()
 }
}

重点是 launch(UI)返回给一个job实例,通过job.cancel()取消coroutine。

Coroutine和thread关系

我们再分析下

launch(UI)

这行代码是指将coroutine指派在UI线程上运行

当我们运行一段cpu耗时操作时,则需要将coroutine指定在非UI线程上。

我们写成:

launch(){...}

这行代码等价于:

launch(CommonPool){...}

我们分析下CommonPool的实现,发现它会根据当前cpu的核数创建一个线程池提供给Coroutine使用。

 private fun createPlainPool(): ExecutorService {
  val threadId = AtomicInteger()
  return Executors.newFixedThreadPool(defaultParallelism()) {
   Thread(it, "CommonPool-worker-${threadId.incrementAndGet()}").apply { isDaemon = true }
  }
 }

 private fun defaultParallelism() = (Runtime.getRuntime().availableProcessors() - 1).coerceAtLeast(1)

总结:

通过上面的分析,我们理解了Coroutine是一个运行在线程上的可被挂起的计算单元实例,对Coroutine的delay,cancel操作不会影响线程的运行,线程的状态变化对我们是透明的,我们不需要关心。

所以使用Coroutine,可以使我们更加方便得处理异步操作,比如网络请求,数据存储等。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 利用Kotlin的协程实现简单的异步加载详解

    前言 众所周知在android中当执行程序的耗时超过5秒时就会引发ANR而导致程序崩溃.由于UI的更新操作是在UI主线程进行的,理想状态下每秒展示60帧时人眼感受不到卡顿,1000ms/60帧,即每帧绘制时间不应超过16.67ms.如果某项操作的耗时超过这一数值就会导致UI卡顿.因此在实际的开发中我通常把耗时操作放在一个新的线程中(比如从网络获取数据,从SD卡读取图片等操作),但是呢在android中UI的更新只能在UI主线程中进行更新,因此当我们在非UI线程中执行某些操作的时候想要更新UI就需

  • 一篇文章揭开Kotlin协程的神秘面纱

    前言 Kotlin协程提供了一种新的异步执行方式,但直接查看库函数可能会有点混乱,本文中尝试揭开协程的神秘面纱. 理论 它是什么 这是别人翻译: 协程把异步编程放入库中来简化这类操作.程序逻辑在协程中顺序表述,而底层的库会将其转换为异步操作.库会将相关的用户代码打包成回调,订阅相关事件,调度其执行到不同的线程(甚至不同的机器),而代码依然想顺序执行那么简单. 我的理解:子任务程协作运行,优雅的处理异步问题解决方案. 它能干什么? 我在做安卓开发,它能替换掉Handler,AsyncTask 甚至

  • Kotlin学习教程之协程Coroutine

    定义 Coroutine翻译为协程,Google翻译为协同程序,一般也称为轻量级线程,但需要注意的是线程是操作系统里的定义概念,而协程是程序语言实现的一套异步处理的方法. 在Kotlin文档中,Coroutine定义为一个可被挂起的计算实例,下面话不多说了,来一起看看详细的介绍吧. 配置 build.gradle中dependencies 添加下面2行,注意coroutine目前仍处于experiment阶段,但Kotline官方保证向前兼容. dependencies { implementa

  • Python并发编程协程(Coroutine)之Gevent详解

    Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporateroutine的缩写,直接翻译为协同的例程,一般我们都简称为协程. 在linux系统中,线程就是轻量级的进程,而我们通常也把协程称为轻量级的线程即微线程. 进程和协程 下面对比一下进程和协程的相同点和不同点: 相同点: 我们都可以把他们看做是一种执行流,执行流可以挂起,并且后面可以在你挂起的地方恢复执行,这实际上都可以看做是con

  • 详细解读tornado协程(coroutine)原理

    tornado中的协程是如何工作的 协程定义 Coroutines are computer program components that generalize subroutines for nonpreemptive multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations.. -- [ 维基百科 ] 我们在平常编程中,更习惯使用的是子

  • Kotlin学习教程之函数的默认参数

    前言 ​ 在Java中,为函数的参数添加默认值是不被允许的,这是为了防止默认参数与函数重载同时使用时二义性的问题,考虑下面的例子: void func(p1: String, p2: String, p3: String = "default") { // do something } void func(String p1, String p2) { // do something } 假设上面的代码是可以编译通过的,那么当调用func("p1","p2

  • C++20中的协程(Coroutine)的实现

    C++20中的协程(Coroutine) 从2017年开始, 协程(Coroutine)的概念就开始被建议加入C++20的标准中了,并已经开始有人对C++20协程的提案进行了介绍.1事实上,协程的概念在很早就出现了,甚至其他语言(JS,Python,C#等)早就已经支持了协程. 可见,协程并不是C++所特有的概念. 那么,什么是协程? 简单来说,协程就是一种特殊的函数,它可以在函数执行到某个地方的时候暂停执行,返回给调用者或恢复者(可以有一个返回值),并允许随后从暂停的地方恢复继续执行.注意,这

  • Python中的协程(Coroutine)操作模块(greenlet、gevent)

    目录 一.协程介绍 1.介绍 2.举例 3.优点如下: 4.缺点如下: 5.总结协程特点: 二.greenlet(绿叶)模块 1.安装模块 2.greenlet实现状态切换 3.效率对比 三.gevent模块 1.安装 2. 用法介绍 1.遇到io主动切换 2. 查看threading.current_thread().getName() 3.Gevent之同步与异步 4.Gevent之应用 1. 服务端 2.多线程并发多个客户端 一.协程介绍 协程:英文名Coroutine,是单线程下的并发,

  • Lua的协程(coroutine)简介

    协程和多线程下的线程类似:有自己的堆栈,自己的局部变量,有自己的指令指针,但是和其他协程程序共享全局变量等信息.线程和协程的主要不同在于:多处理器的情况下,概念上来说多线程是同时运行多个线程,而协程是通过协作来完成,任何时刻只有一个协程程序在运行.并且这个在运行的协程只有明确被要求挂起时才会被挂起 你可以使用coroutine.create来创建协程: 复制代码 代码如下: co = coroutine.create(function ()      print("hi") end)

  • Kotlin学习教程之操作符重载详解

    前言 在 Kotlin 中,我们可以用 约定的操作符,代替 调用代码中以特定的命名定义的函数,来实现 与之对应的操作.例如在类中定义了一个名为 plus 的特殊方法,就可以使用加法运算符 + 代替 plus() 的方法调用.由于你无法修改已有的接口定义,因此一般可以通过 扩展函数 来为现有的类增添新的 约定方法,从而使得 操作符重载 这一语法糖适应任何现有的 Java 类. 算术运算符 我们就从最简单直接的例子 + 这一类算术运算符开始. data class Point(val x: Int,

  • 深入理解 Java、Kotlin、Go 的线程和协程

    前言 Go 语言比 Java 语言性能优越的一个原因,就是轻量级线程Goroutines(协程Coroutine).本篇文章深入分析下 Java 的线程和 Go 的协程. 协程是什么 协程并不是 Go 提出来的新概念,其他的一些编程语言,例如:Go.Python 等都可以在语言层面上实现协程,甚至是 Java,也可以通过使用扩展库来间接地支持协程. 当在网上搜索协程时,我们会看到: Kotlin 官方文档说「本质上,协程是轻量级的线程」. 很多博客提到「不需要从用户态切换到内核态」.「是协作式的

  • Kotlin中协程的创建过程详析

    目录 为什么需要协程? 创建并启动协程 协程的执行过程 suspend block 是如何变为协程体被执行的? 总结 总结 为什么需要协程? 协程可以简化异步编程,可以顺序地表达程序,协程也提供了一种避免阻塞线程并用更廉价.更可控的操作替代线程阻塞的方法 – 挂起函数. Kotlin 的协程是依靠编译器实现的, 并不需要操作系统和硬件的支持.编译器为了让开发者编写代码更简单方便, 提供了一些关键字(例如suspend), 并在内部自动生成了一些支持型的代码. 创建并启动协程 fun create

随机推荐