Kotlin 协程思维模型的引入使用建立

目录
  • 1.协程
  • 2.Kotlin协程
    • 1.引入Kotlin协程
    • 2.Kotlin协程的使用
    • 3.Kotlin协程的轻量(总结的还不够清晰)
    • 4.协程的“非阻塞式”
    • 5.建立思维模型

1.协程

协程不是进程或线程,它的执行过程更类似于子例程或者说不带返回值的函数调用。

一个程序可以包含多个协程,类似于一个进程包含多个线程。线程有自己的上下文多个线程存在时它们相对独立,切换受系统控制,而协程也相对独立,也有自己的上下文,但是切换是由自己控制的,当需要切换到其他协程时是由当前协程控制的。

线程 协程
独立性 相对独立 相对独立
上下文 有自己的上下文 有自己的上下文
切换 系统决定是否切换 当前协程决定是否切换

2.Kotlin协程

1.引入Kotlin协程

Kotlin中如果要使用协程是需要添加依赖的,它没有被集成在标准库中,单独拎出来主要是为了减小标准库的体积

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'

那么要如何理解Kotlin协程?Kotlin协程可以理解为更轻量级的线程,协程的运行离不开线程,这有点像线程和进程之间的关系。

2.Kotlin协程的使用

fun main() = runBlocking {
    doWorld()
}
suspend fun doWorld() = coroutineScope {
    launch {
        delay(1000L)
        println("World!")
    }
    println("Hello")
}
//输出结果:
//Hello
//World!

上面的代码是Kotlin协程的一个简单例子其中runBlockingcoroutineScopelaunch是协程作用域,suspend是挂起,delay(1000L)是一个延时函数。从结果来看我们的代码顺序和输出结果的顺序不一样,这就是Kotlin协程的魅力,我们看下面的流程图:

3.Kotlin协程的轻量(总结的还不够清晰)

  • 启动 10 亿个线程,这样的代码运行在大部分的机器上都是会因为内存不足等原因而异常退出的。那么启动10亿个协程则不会出现异常因为协程是非常轻量的;
  • 协程虽然是运行在线程上的但是它并不会与某个线程绑定,而且还可以在不同线程之间切换。

4.协程的“非阻塞式”

线程是阻塞的,因为它在运行一个耗时任务时只有这个任务完成了才会执行后面的任务,而Kotlin在执行一个耗时任务时会把这个任务放入后台执行,去执行下一个任务。

fun main() {
    repeat(3) {
        Thread.sleep(1000L)
        println("Print-1:${Thread.currentThread().name}")
    }
    repeat(3) {
        Thread.sleep(900L)
        println("Print-2:${Thread.currentThread().name}")
    }
}
/*
输出结果:
Print-1:main
Print-1:main
Print-1:main
Print-2:main
Print-2:main
Print-2:main
*/

上面的代码是阻塞式任务,可以看到两个任务之间的等待时差是100毫秒,但是第二个repeat执行的前提是第一个repeat执行完毕,那么这个任务的最终耗时就是5700毫秒。

fun main() = runBlocking {
    launch {
        repeat(3) {
            delay(1000L)
            println("Print-1:${Thread.currentThread().name}")
        }
    }
    launch {
        repeat(3) {
            delay(900L)
            println("Print-2:${Thread.currentThread().name}")
        }
    }
    delay(3000L)
}
/*
输出结果:
Print-2:main @coroutine#3
Print-1:main @coroutine#2
Print-2:main @coroutine#3
Print-1:main @coroutine#2
Print-2:main @coroutine#3
Print-1:main @coroutine#2
*/

上面的代码是非阻塞式任务,可以看到两个任务之间的等待时差是100毫秒,第以个repeat和第二个repeat是同时执行的,也就是说他们同时开始执行,当达到900毫秒时第二个repeat开始执行,当达到1000毫秒时第一个repeat开始执行,那么这个任务的最终耗时就是3000毫秒。

由此可见,Kotlin 协程的“非阻塞”其实只是语言层面的,当我们调用 JVM 层面的 Thread.sleep() 的时候,它仍然会变成阻塞式的。与此同时,这也意味着我们在协程当中应该尽量避免出现阻塞式的行为。尽量使用 delay,而不是 sleep。

到这里其实就会产生一个疑问,delay就能解决阻塞的问题吗?答案是不是,解决阻塞问题的其实是Kotlin的挂起和恢复的能力,这是协程才拥有的特殊能力。

挂起和恢复又该怎么理解呢,举个例子,现在有两件事情:①烧一壶水烧开后断开电源;②做饭;第一件事是一个耗时任务,开始烧水后我去做第二件事这就是挂起,当水烧开以后要去断开电源这就是恢复。

5.建立思维模型

Kotlin的协程要比Java线程更抽象,因为Java的线程可以找到Thread的源码,同时线程也是操作系统中的一个概念,所以理解起来较为简单。而Kotlin的协程没有类似的知识点可以建立关联,所以在学习Kotlin协程的时候就需要简历协程的思维模型, 没有这个思维理解Kotlin协程就比较难。

如何建立Kotlin的思维模型?可以将Kotlin协程想象成一个“更加轻量级的线程”。

从包含关系上看,协程跟线程的关系,有点像线程与进程的关系,毕竟协程不可能脱离线程运行。所以,协程可以理解为运行在线程当中的、更加轻量的 Task

以上就是Kotlin 协程思维模型的引入使用建立的详细内容,更多关于Kotlin 协程思维模型的资料请关注我们其它相关文章!

(0)

相关推荐

  • Kotlin协程launch启动流程原理详解

    目录 1.launch启动流程 反编译后的Java代码 2.协程是如何被启动的 1.launch启动流程 已知协程的启动方式之一是Globalscope.launch,那么Globalscope.launch的流程是怎样的呢,直接进入launch的源码开始看起. fun main() { coroutineTest() Thread.sleep(2000L) } val block = suspend { println("Hello") delay(1000L) println(&q

  • Kotlin协程Job生命周期结构化并发详解

    目录 1.Job的生命周期 2.Deffered 3.Job与结构化并发 4.launch和async的使用场景 前面在学习协程启动方式的时候在launch的源码中有一个返回值是Job,async的返回Deferred也是实现了Job,那么而也就是说launch和async在创建一个协程的时候也会创建一个对应的Job对象.还提到过Job是协程的句柄,那么Job到底是什么?它有什么用? 1.Job的生命周期 先看一下Job的源码,这里只保留了跟标题相关的内容 public interface Jo

  • Kotlin coroutineContext源码层深入分析

    目录 1.CoroutineContext 2.Element的作用 3.CoroutineContext相关的操作符原理解析 3.1.什么类型的集合 3.2.如何管理 Element combinedContext 4.验证以及总结 1.CoroutineContext 表示一个元素或者是元素集合的接口.它有一个Key(索引)的Element实例集合,每一个Element的实例也是一个CoroutineContext,即集合中每个元素也是集合. 如下图所示,CoroutineContext的常

  • Kotlin协程Context应用使用示例详解

    目录 1.Context的应用 2.万物皆有 Context 1.CoroutineScope 2.Job 3.Dispatcher 4.CoroutineExceptionHandler 1.Context的应用 Context在启动协程模式中就已经遇到过叫CoroutineContext,它的意思就是协程上下文,线程的切换离不开它. 在启动协程模式中也说明过为什么不用传递Context,因为它有一个默认值EmptyCoroutineContext,需要注意的是这个Context是不可以切换线

  • Kotlin1.6.20新功能Context Receivers使用技巧揭秘

    目录 前言 扩展函数的局限性 什么是 Context Receivers 如何使用 Context Receivers 引入 Context Receivers 导致可读性问题 Context Receivers 应用范围及注意事项 总结 前言 这篇文章我们一起来聊一下 Kotlin 1.6.20 的新功能 Context Receivers,来看看它为我们解决了什么问题. 通过这篇文章将会学习到以下内容: 扩展函数的局限性 什么是 Context Receivers,以及如何使用 Contex

  • kotlin Context使用详解

    在activity级下使用this表示context kotlin中取消了xxxActivity.this的用法,所以我们可以在activity下新建一个Context属性--instance指向它本身.然后在其他地方使用.如果使用的地方是在activity这一级则可以直接使用this指向它本身 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentVie

  • Kotlin协程Flow生命周期及异常处理浅析

    目录 正文 Flow基本概念 Flow生命周期 处理异常 上游或者中间异常使用catch 下游使用try-catch 切换执行线程 终止操作符 "冷的数据流"从何而来 正文 Kotlin协程中的Flow主要用于处理复杂的异步数据,以一种”流“的方式,从上到下依次处理,和RxJava的处理方式类型,但是比后者更加强大. Flow基本概念 Flow中基本上有三个概念,即 发送方,处理中间层,接收方,可以类比水利发电站中的上游,发电站,下游的概念, 数据从上游开始发送”流淌“至中间站被”处理

  • Kotlin协程Channel特点及使用细节详解

    目录 正文 1.认识Channel 2.Channel使用中的细节 3.Channe的特点 正文 在协程启动模式中已经知道async是可以返回结果的,但是只返回一个,那么在复杂场景下就会不够用了,所以Channel就出现了. 1.认识Channel Channel的意思是管道.通道,用图表示如下: Channel的左边是发送方,右边是接收方,中间则是消息,那么代码表示就是下面这样: fun main() { channelTest() } fun channelTest() = runBlock

  • Kotlin 协程思维模型的引入使用建立

    目录 1.协程 2.Kotlin协程 1.引入Kotlin协程 2.Kotlin协程的使用 3.Kotlin协程的轻量(总结的还不够清晰) 4.协程的“非阻塞式” 5.建立思维模型 1.协程 协程不是进程或线程,它的执行过程更类似于子例程或者说不带返回值的函数调用. 一个程序可以包含多个协程,类似于一个进程包含多个线程.线程有自己的上下文多个线程存在时它们相对独立,切换受系统控制,而协程也相对独立,也有自己的上下文,但是切换是由自己控制的,当需要切换到其他协程时是由当前协程控制的. 线程 协程

  • 使用kotlin协程提高app性能(译)

    协程是一种并发设计模式,您可以在Android上使用它来简化异步执行的代码.Kotlin1.3版本添加了 Coroutines,并基于其他语言的既定概念. 在Android上,协程有助于解决两个主要问题: 管理长时间运行的任务,否则可能会阻止主线程并导致应用冻结. 提供主安全性,或从主线程安全地调用网络或磁盘操作. 本主题描述了如何使用Kotlin协程解决这些问题,使您能够编写更清晰,更简洁的应用程序代码. 管理长时间运行的任务 在Android上,每个应用程序都有一个主线程来处理用户界面并管理

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

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

  • Android kotlin+协程+Room数据库的简单使用

    Room Room是Google为了简化旧版的SQLite操作专门提供的 1.拥有了SQLite的所有操作功能 2.使用简单(类似于Retrofit),通过注解的方式实现相关功能.编译时自动生成实现类impl 3.LiveData,LifeCycle,Paging天然融合支持 导入 ... plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' id 'kotlin-kap

  • Kotlin协程到底是如何切换线程的

    随着kotlin在Android开发领域越来越火,协程在各个项目中的应用也逐渐变得广泛 但是协程到底是什么呢? 协程其实是个古老的概念,已经非常成熟了,但大家对它的概念一直存在各种疑问,众说纷纷 有人说协程是轻量级的线程,也有人说kotlin协程其实本质是一套线程切换方案 显然这对初学者不太友好,当不清楚一个东西是什么的时候,就很难进入为什么和怎么办的阶段了 本文主要就是回答这个问题,主要包括以下内容 1.关于协程的一些前置知识 2.协程到底是什么? 3.kotlin协程的一些基本概念,挂起函数

  • Kotlin协程上下文与上下文元素深入理解

    目录 一.EmptyCoroutineContext 二.CombinedContext 三.Key与Element 四.CoroutineContext 五.AbstractCoroutineContextKey与AbstractCoroutineContextElement 一.EmptyCoroutineContext EmptyCoroutineContext代表空上下文,由于自身为空,因此get方法的返回值是空的,fold方法直接返回传入的初始值,plus方法也是直接返回传入的cont

  • Kotlin协程概念原理与使用万字梳理

    目录 一.协程概述 1.概念 2.特点 3.原理 二.协程基础 1.协程的上下文 2.协程的作用域 3.协程调度器 4.协程的启动模式 5.协程的生命周期 三.协程使用 1.协程的启动 2.协程间通信 3.多路复用 4.序列生成器 5.协程异步流 6.全局上下文 一.协程概述 1.概念 协程是Coroutine的中文简称,co表示协同.协作,routine表示程序.协程可以理解为多个互相协作的程序.协程是轻量级的线程,它的轻量体现在启动和切换,协程的启动不需要申请额外的堆栈空间:协程的切换发生在

  • Kotlin协程操作之创建启动挂起恢复详解

    目录 一.协程的创建 1.start方法 2.CoroutineStart类 3.startCoroutineCancellable方法 4.createCoroutineUnintercepted方法 5.createCoroutineFromSuspendFunction方法 二.协程的启动 1.ContinuationImpl类 2.resumeCancellableWith方法 3.BaseContinuationImpl类 4.invokeSuspend方法 三.协程的挂起与恢复 下面

  • Kotlin协程launch原理详解

    目录 正文 launch使用 launch原理 CoroutineStart中找invoke方法 startCoroutineCancellable逻辑 小结 正文 launch我们经常用,今天来看看它是什么原理. 建议: 食用本篇文章之前记得先食用Kotlin协程之createCoroutine和startCoroutine launch使用 launch我们应该很熟悉了,随便举个例子: fun main() { val coroutineScope = CoroutineScope(Job(

  • Kotlin协程启动createCoroutine及创建startCoroutine原理

    目录 createCoroutine 和 startCoroutine startCoroutine调用 createCoroutineUnintercepted intercepted resume 结语 createCoroutine 和 startCoroutine 协程到底是怎么创建和启动的?本篇文章带你揭晓. 在Continuation.kt文件中,有2个基础API,这里单独提出来说一下,方便后面我们理解launch. public fun <T> (suspend () ->

随机推荐