Kotlin高级协程

news2024/11/17 7:40:19

Kotlin高级协程

  • 一.前言
  • 二.先从线程说起
  • 三.协程的设计思想
  • 四.协程特点:优雅的实现移步任务
  • 五.协程基本使用
  • 六.协程和线程相比有什么特点,如何优雅的实现异步任务

一.前言

在文章正式上干货之前,先说一点背景吧;我是 Kotlin 协程官方文档的译者,大家在 Kotlin 中文官网上看到的绝大多数协程的中文官方文档都是我翻译的。

官方文档可以说是比较全面的介绍了协程的使用,但是就我的感觉来说,这些文档分布的比较散乱,甚至还有三篇分布在协程的官方 Github 的 project 中,很多协程的初学者对这些文档的阅读顺序也尝尝感到摸不到头脑。这里我将一共 15 篇文档的学习顺序做一个整理,如果你还不了解如何使用协程,可以参考我如下的列举:

首先,如果您不了解什么是协程,以及不清楚如何将协程引入您的项目,你可以按顺序阅读这两篇教程:
《异步程序设计》
《JVM 平台的 Kotlin 协程简介》

接下来两篇官方文档类似于导读或目录,简述了一下协程的理念,以及给出了一些干货的链接,这两篇导读本身倒是没啥干货:
《用于异步编程等场景的协程》
《协程指南》
然后就是大量的正餐了,如下八篇官方文档介绍了协程使用的方方面面,一定要读懂:

《基础》
《取消与超时》
《通道》
《组合挂起函数》
《协程上下文与调度器》
《异常处理》
《Select 表达式》
《共享的可变状态与并发》
上面八篇文档读完,再配以大量的实践,你应该已经掌握了协程的基本用法,并开始思考使用它的场景,你可能想知道如何使用协程编写 UI 应用程序,亦或是你可能对协程和响应式流(例如 RxJava)之间的异同和关系有疑问,那么可以参考下面两篇被刊登在官方 Github 上的指南:

《使用协程进行 UI 编程指南》
《响应式流与协程指南》
现在你应该已经掌握协程在绝大多数场景下的用法,于是你可能好奇于它的实现原理,那么可以阅读这篇官方 Keep:

《协程设计文档(KEEP)》
目前这就是协程全部的官方资料,两篇指南和一篇 Keep,都是刊登在 Github 上的;目前 Kotlin 中文站的站长是灰蓝天际老哥,所以上面给出的指向 Github 的地址是指向他 Fork 的版本,以上所有文档的英文原版,都可以在 Kotlin 的英文官网,以及官方的 Github 上找到。

Kotlin 目前是一门多平台语言,虽然协程的设计思想是统一的,但它们在底层的实现原理上会有所不同,例如,在 JVM 和 Android 上,协程的实现要基于线程池的 API,但是在 JS 平台上,由于 JS 本身不支持多线程,所以协程这时必定就不会产生并发。作为一名 Android 工程师,本位将致力于阐述协程在 Android 平台和 JVM 平台的原理,而 JS 平台以及众多的 Native 平台则暂不讨论。

本文将会先介绍一些协程的设计思想,然后详细讲解一下协程的编译相关以及标准库等内容,然后根据源码深入到协程调度器的底层实现细节(调度器这一部分我认为是最值得去看的)。

二.先从线程说起

协程和线程的关系密不可分,为了能准确的阐述协程的行为,这里有必要先简单描述一下线程是如何执行的。

线程是操作系统的内核资源,是 CPU 调度的最小单位,所有应用程序的代码都运行于线程之上。

无论是回调,还是 RxJava,又或者是 Future 与 Promise,线程都是我们曾经实现并发与异步的最根本的支撑。在 Java 的 API 中,Thread 类是实现线程最基本的类,每创建一个 Thread 对象,就代表着在操作系统内核启动了一个线程,如果我们阅读 Thread 类的源码,可以发现,它的内部实现是大量的 JNI 调用,因为线程的实现必须由操作系统直接提供支持,如果是在 Android 平台上,我们会发现 Thread 的创建过程中,都会调用 Linux API 中的 pthread_create 函数,这直接说明了 Java 层中的 Thread 和 Linux 系统级别的中的线程是一一对应的。

线程的调用存在以下几个问题;首先,线程阻塞与运行两种状态之间的切换有相当大的开销,在传统的线程调用中,线程状态切换的开销一直是程序中一个较大的优化点,例如 Java 在编译时会对锁进行各种优化,例如自旋锁,锁粗化,锁消除等。其次,线程并非是一种轻量级资源,大量创建线程是对系统资源的一种消耗,而传统的阻塞调用会导致系统中存在大量因阻塞而不运行的线程,这对系统资源是一种极大的浪费。

协程与线程不同;首先,协程本质上可以认为是运行在线程上的代码块,协程提供的 挂起 操作会使协程暂停执行,而不会导致线程阻塞。其次,协程是一种轻量级资源,即使创建了上千个协程,对于系统来说也不是一种很大的负担,就如同在 Java 创建上千个 Runable 对象也不会造成过大负担一样。通过这样设计,开发者可以极大的提高线程的使用率,用尽量少的线程执行尽量多的任务,其次调用者无需在编程时思考过多的资源浪费问题,可以在每当有异步或并发需求的时候就不假思索的开启协程。

三.协程的设计思想

在 Kotlin 中,为了保证安装程序包不会太大(这在 Android 这种嵌入式平台上非常有意义),通常将一些非必须的功能隔离到扩展包中,使用者仅仅在需要时才将它们引入,例如 kotlinx.io(IO)、kotlinx.serialization(序列化)、kotlinx.html(DSL 构建 HTML)、kotlinx.coroutines(协程)等等;这些库我们称之为扩展库,如果我们要使用协程,必须将扩展库引入项目工程,用户直接使用的绝大多数 API 例如:launch、async 等等都由扩展库提供;但是协程从不仅仅是一个库这么简单,它属于 Kotlin 1.3 新增的一种语言特性,所以它的标准库中提供了协程实现的基本原语,扩展库实际上是对这些更底层 API 的封装;除此之外,我们定义挂起函数的“suspend”修饰符属于语言层面的东西,因此需要编译器的直接支持;虽然只有一个“suspend”修饰符,但编译器承担了实现协程的绝大部分任务,可以说是协程的核心,因此在协程的设计思想中,编译器占据了主要的地位,而本节的内容大多数也正是围绕编译器展开。

四.协程特点:优雅的实现移步任务

五.协程基本使用

https://blog.51cto.com/u_12127193/5753600
依赖:

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

最简单的实现协程:

GlobalScope.launch {
    Log.d(TAG, Thread.currentThread().name)
}

运行结果如下:
在这里插入图片描述
上面的代码协程运行在子线程中,也可以传参在主线程中也可以取消任务

val job = GlobalScope.launch(Dispatchers.Main) {
    Log.d(TAG, Thread.currentThread().name)
}
job.cancel()

六.协程和线程相比有什么特点,如何优雅的实现异步任务

模拟网络请求数据,拿到数据后展示数据,下面2个方法分别模拟网络请求数据和展示数据

/**
 * 从服务器取信息
 */
private fun getMessageFromNetwork(): String {

    for (i in 0..1000000) {
        //这里模拟一个耗时操作
    }
    var name = "Huanglinqing"
    return name
}

/**
 * 显示信息
 * @message :信息
 */
private fun showMessage(message: String) {
    tvName.text = message
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/509521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言初阶之扫雷代码详解(含递归展开)

扫雷代码详解 扫雷代码思路头文件解析主函数解析函数文件解析①初始化函数(InitBoard)②打印函数③难易选项函数(Select)④布雷(SetMine)⑤获取周边雷数(GetMine)⑥展开函数&#xf…

从零开始,轻松打造Web自动化测试框架:Python+Selenium实战指南

在程序员的世界中,一切重复性的工作,都应该通过程序自动执行。「自动化测试」就是一个最好的例子。 随着互联网应用开发周期越来越短,迭代速度越来越快,只会点点点,不懂开发的手工测试,已经无法满足如今的…

广州虚拟动力亮相2023世界元宇宙生态博览会,邀您解锁元宇宙商机

2023年5月10-12日 2023第2届世界元宇宙生态博览会 在广州广交会展馆正式举办! 广州虚拟动力携虚拟数字人全栈式解决方案参展 诚邀您莅临3.2馆A109-A110展位参观交流 2022年全国多个地方出台元宇宙政策文件,各地方政府的元宇宙产业扶持政策也在逐渐细…

webshell及工具

目录 一,Webshell的概念 二,eval函数的定义和用法 三,连接工具菜刀 3.1文件管理 3.2 虚拟终端 3.3 菜刀与burpsuite联动 四,哥斯拉的使用 五,冰蝎 六,webshell分类 七,webshell如何连接 …

哪个牌子的电视盒子好用?罗鹏数码盘点2023电视盒子排名

电视机资源少、卡顿,配置不足的时候只需要安装一台电视盒子就可以解决这些问题,不需要花费大价钱更换电视机。那么,你知道哪个牌子的电视盒子好用吗?今天罗鹏就来详细聊聊这个话题,分享2023最新电视盒子排名。 一&…

在家经济性雾视训练

如何使用睛延宝进行雾视训练,才能缩轴控度? 雾视的相关概念 首先大家要知道什么是雾视? 顾名思义,雾视就是眼睛看目标物时有点模糊,好像有层雾。 雾视的效果:放松睫状肌,拉薄晶状体,增厚脉络膜。 原理就…

如何与劳氏 Lowe‘s 建立EDI连接?

劳氏Lowes(以下简称:Lowes)是专门从事家庭装修的美国零售公司,而 EDI 则是电子数据交换的缩写,是指通过计算机网络进行企业间电子数据交换的一种标准化方式。 通过 EDI,企业与Lowes之间可以直接交换各种商…

【Java笔试强训 35】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥年会抽奖…

六、FM1288调试方案-调试过程及细节

本篇文章,主要讲述实际调试操作:具体到需要调节哪些寄存器,调节完后,会有什么样的变化。但是整体效果不能达到我们期望的绝对感觉,所以我先把我们调试的结果放在前面,如果觉得不理想,也可以不看后面的内容了。 文章目录 1. 调试准备1.1 建立与FM1288芯片通信1.2 Uart结…

IPv6有哪些优势?

现有的互联网是在IPv4协议的基础上运行的。IPv6是下一版本的互联网协议,也可以说是下一代互联网的协议,它的提出最初是因为随着互联网的迅速发展,IPv4定义的有限地址空间将被耗尽,而地址空间的不足必将妨碍互联网的进一步发展。 为…

1.100ASK-V853-PRO编译烧写

100ASK_V853-PRO 环境配置及编译烧写 0.前言 本章主要介绍关于100ASK_V853-PRO开发板的Tina SDK包的下载和编译打包生成镜像,并将镜像烧录到100ASK_V853-PRO开发板上。在进行100ASK_V853-PRO开发板的环境配置前需要获取配置虚拟机系统,可以参考&#x…

【HA】HomeAssistant 添加 小米温湿度计2代

本方法只是被动的获取小米温湿度计广播出的温度和湿度数据,并没有其他更多功能。 0. 本人配置 树莓派3B Debian 11 (Bullseye) 64 位 Supervisor 2023.05.dev0901 HomeAssistant 已安装 HACS 1. 安装 打开侧边栏中的HACS,点击“集成” 右下角找到“…

ACM - DP - 提高2 (状态机 + 状态压缩 + 区间 + 树形 + 数位 + 单调队列优化 + 斜率优化)

DP 类型题二 【跳转DP 类型题一 (模型:数字三角形最长上升子序列背包】一、状态机模型1、AcWing 1057. 股票买卖 IV :两个状态转换2、AcWing 1058. 股票买卖 V :三个状态转换3、AcWing 1052. 设计密码 :T 维状态转换 …

IDEA创建接口类和接口实现类

IDEA创建接口类和接口实现类 IDEA创建接口类IDEA创建接口实现类 以创建Dao包下的代码为例。 IDEA创建接口类 选中要创建接口类的package,右键菜单依次选择New——Java Class。 在弹出的界面中,将创建的对象类型由Class改为Interface,如下图…

Jmeter接口测试流程详解

1、jmeter简介 Jmeter是由Apache公司开发的java开源项目,所以想要使用它必须基于java环境才可以; Jmeter采用多线程,允许通过多个线程并发取样或通过独立的线程对不同的功能同时取样。 2、jmeter安装 首先需要安装jdk(最好是最…

“锻造”微生物组以帮助我们长寿和繁荣

谷禾健康 衰老通常伴随着心血管、神经和免疫系统等一系列疾病的风险增加。 虽然在理解微生物组导致与衰老相关的个别疾病的细胞和分子机制方面取得了显著进展,我们在之前的文章也有这方面的阐述: 肠道微生物群与健康长寿 肠道微生物群的老化及其对宿主免…

二、Linux入门| shell运行原理及Linux权限的理解

一、Linux 软件包管理器 - yum centos7的安装方式 1、源码安装(较复杂) 2、rpm包安装(较复杂,未解决依赖关系) 3、yum安装(不用编译源码,不用解决软件的依赖关系,门槛较低&#xff…

LeetCode4. 寻找两个正序数组的中位数

写在前面: 题目链接:LeetCode4. 寻找两个正序数组的中位数 编程语言:C 题目难度:困难 一、题目描述 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中…

英文论文润色哪家好用比较好,有值得推荐的吗

英文论文润色 推荐 英文论文润色对于写作者来说是一项十分重要的任务,它可以帮助我们修改文章中的语法、标点和排版等问题,使论文更加准确和易读。在众多的英文润色软件中,147chatgpt改写润色软件是一款值得推荐的全自动批量图文润色、自动纠…

SSM框架学习-核心容器小结

1. 容器相关 Spring核心容器中的容器是指容器对象,用于管理和装配Bean。它主要包含以下四个容器: BeanFactory容器:是最简单的容器,提供实例化、配置和管理对象的基本功能,但不提供AOP、事务管理等高级功能。 Applica…