枯燥的Kotlin协程三部曲(上)——概念启蒙篇(上)

简介: Kotlin 1.3 版本开始引入协程 Coroutine,简练的官方文档 和 网上一堆浅尝辄止的文章让我心里没底,不想止步于仅仅知道: ① Android中,Kotlin协程用于解决:处理耗时任务 和 保证主线程安全;② 利用Kotlin协程,可以用看起来:同步 的方式编写 异步 代码;③ 基础的API调用;

0x0、引言


Kotlin 1.3 版本开始引入协程 Coroutine,简练的官方文档 和 网上一堆浅尝辄止的文章让我心里没底,不想止步于仅仅知道:


① Android中,Kotlin协程用于解决:处理耗时任务保证主线程安全

② 利用Kotlin协程,可以用看起来:同步 的方式编写 异步 代码;

③ 基础的API调用;


我还想了解更多,如协程的概念,Kotlin协程在实际开发中的使用,背后的原理等,遂有此文。


Kotlin协程的源码还没啃完,此系列目前只能算是笔记,边看边学,部分内容摘取自参考文献,只是让潜意识里有这些概念,后续看完源码,缕清思路再来整理一波,有纰漏之处,欢迎评论区友善指出,一起讨论学习,谢谢~


本文主要阐述一些概念相关的东西,一些前置知识,有所了解得可直接跳过。


0x1、追根溯源


1、同步 & 异步


先撇开编程相关的东西不说,通过 坐公交 的形象化例子帮助理解 同步与异步:


乘客排队等公交,车来了,前门扫码上车,一个扫完到下一个扫,一种 串行化 的关系,这是 同步


前门乘客上车,后门乘客下车,互不影响,同时进行,一种 并行化 的关系,这是 异步


我们把乘客上车和下车,看做是两个 任务,司机开车也是一个任务,跟这两个任务是异步关系。异步说明两者可以同时进行,乘客还没上完车,司机直接把车开走,也是可以的:


不过这显然不合常理,正常来说:司机应该等乘客上下车完毕才发车,那司机怎么知道:


常规操作有两种:


轮询(主动):每隔一段时间查看下前后门监控,看下还有没有乘客;


回调(被动):早期的公交车上都会配有一个乘车员,没乘客上下车了,她就会喊司机开车;


2、堵塞 & 非堵塞


同步和异步的关注点是 是否同时进行,而堵塞和非堵塞关注的是 能否继续进行,还是坐公交的例子:


有乘客上下车,司机发车就需要等待,此时司机发车的任务处于 堵塞 状态;


乘客都上下车完毕,司机又可以发车了,此时司机发车的任务处于 非堵塞 状态;


堵塞的真正含义:关心的事物由于某些原因,无法继续进行,因此让你等待。


等待:只是堵塞的一个副作用,表明随时间流逝,没有任何有意义的事物发生或进行。


堵塞时,没必要干等着,可以做点其他无关的事物,因为这不影响你对相关事情的等待;


比如司机等发车时,可以喝喝茶、看看手机等,但不能离开。


计算机没人那么灵活,堵塞时干等最容易实现,只需挂起线程,让出CPU即可,等条件满足时,在重新调度此线程。


3、程序


回到编程相关,任务 对应计算机中的 程序,定义如下:


为了完成特定任务,用某种编程语言编写的一组指令集合(一组 静态代码)


CPU处理器逐条执行指令,哪怕出现外部中断,也只是从当前程序切到另一段程序,继续逐条执行。



和预期一致,代码 逐条执行,但有些业务场景 顺序结构 就无能为力了,比如:


女朋友:你下班后去超市买10个鸡蛋回来,看到有卖西瓜的就买1个


此时,需要用到四种 基础控制流 中的另外一种 → 选择执行



剩下两种基础控制流为 迭代和递归,我们使用 控制流 来完成 逻辑流,程序执行到哪,逻辑就执行到哪,这样的程序结构清晰,可读性好,比较符合编程人员的思维习惯,这也是 同步编程 的方式。


4、进程


同一时刻只有一个程序在内存中被CPU调用运行


假设有A、B两个程序,A正在运行,此时需要读取大量输入数据(IO操作),那么CPU只能干等,直到A数据读取完毕,再继续往下执行,A执行完,再去执行程序B,白白浪费CPU资源。


看着有点蠢,能不能这样:


当程序A读取数据的时,切换 到程序B去执行,当A读取完数据,让程序B暂停,切换 回程序A执行?


当然可以,不过在计算机里 切换 这个名词被细分为两种状态:


挂起:保存程序的当前状态,暂停当前程序;


激活:恢复程序状态,继续执行程序;


这种切换,涉及到了 程序状态的保存和恢复,而且程序A和B所需的系统资源(内存、硬盘等)是不一样的,那还需要一个东西来记录程序A和B各自需要什么资源,还有系统控制程序A和B切换,要一个标志来识别等等,所以就有了一个叫 进程的抽象


进程的定义


程序在一个数据集上的一次动态执行过程,一般由下述三个部分组成:


  • 程序:描述进程要完成的功能及如何完成;


  • 数据集:程序在执行过程中所需的资源;


  • 进程控制块:记录进程的外部特征,描述执行变化过程,系统利用它来控制、管理进程,系统感知进程存在的唯一标志。


进程是系统进行 资源分配和调度 的一个 独立单位


进程的出现使得多个程序得以 并发 执行,提高了系统效率及资源利用率,但存在下述问题:


① 单个进程只能干一件事,进程中的代码依旧是串行执行。


② 执行过程如果堵塞,整个进程就会挂起,即使进程中某些工作不依赖于正在等待的资源,也不会执行。


③ 多个进程间的内存无法共享,进程间通讯比较麻烦。


于是划分粒度更小的 线程 出现了。


5、线程


线程的出现是为了降低上下文切换消耗,提高系统的并发性,并突破一个进程只能干一件事的缺陷,使得 进程内并发 成为可能。


线程的定义


轻量级的进程,基本的CPU执行单元,亦是 程序执行过程中的最小单元,由 线程ID、程序计数器、寄存器组合和堆栈 共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能。


区分:「进程」是「资源分配」的最小单位,「线程」是 「CPU调度」的最小单位

线程和进程的关系


① 一个程序至少有一个进程,一个进程至少有一个线程,可以把进程理解做 线程的容器

② 进程在执行过程中拥有 独立的内存单元,该进程里的多个线程 共享内存

③ 进程可以拓展到 多机,线程最多适合 多核

④ 每个独立线程有一个程序运行的入口、顺序执行列和程序出口,但不能独立运行,需依存于应用程序中,由应用程序提供多个线程执行控制;


进程和线程都是一个时间段的描述,是 CPU工作时间段的描述,只是颗粒大小不同。


相关文章
|
7月前
|
Java 数据库 Android开发
【专栏】Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理
【4月更文挑战第27天】本文探讨了Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理。通过案例分析展示了网络请求、图像处理和数据库操作的优化实践。同时,文章指出并发编程的挑战,如性能评估、调试及兼容性问题,并强调了多线程优化对提升应用性能的重要性。开发者应持续学习和探索新的优化策略,以适应移动应用市场的竞争需求。
180 5
|
7月前
|
传感器 Android开发 开发者
构建高效Android应用:Kotlin的协程与Flow
【4月更文挑战第26天】随着移动应用开发的不断进步,开发者寻求更简洁高效的编码方式以应对复杂多变的业务需求。在众多技术方案中,Kotlin语言凭借其简洁性和强大的功能库逐渐成为Android开发的主流选择。特别是Kotlin的协程和Flow这两个特性,它们为处理异步任务和数据流提供了强大而灵活的工具。本文将深入探讨如何通过Kotlin协程和Flow来优化Android应用性能,实现更加流畅的用户体验,并展示在实际开发中的应用实例。
|
7月前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin与协程的完美融合
【2月更文挑战第25天】 在移动开发领域,性能优化和应用响应性的提升是永恒的追求。随着Android Jetpack组件库的不断丰富,Kotlin语言已经成为Android开发的首选。而Kotlin协程作为一种新的并发处理方案,它以轻量级线程的形式,为开发者提供了简洁高效的异步编程手段。本文将深入探讨Kotlin协程在Android应用中的实践运用,以及如何通过这种技术改善用户界面的流畅度和后台任务的处理能力,进而构建出更高效、更稳定的Android应用。
|
7月前
|
安全 Android开发 开发者
构建高效Android应用:Kotlin与协程的完美结合
【2月更文挑战第30天】在移动开发领域,性能优化和流畅的用户体验是关键。本文深入探讨了如何通过结合Kotlin语言和协程技术来提升Android应用的性能和响应能力。我们将分析Kotlin的优势,介绍协程的基本概念,并通过实际案例展示如何在应用中实现协程以简化异步编程,从而提供更加高效的解决方案。
|
4月前
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
6月前
|
分布式计算 JavaScript 前端开发
多线程、多进程、协程的概念、区别与联系
多线程、多进程、协程的概念、区别与联系
98 1
|
2月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
30 1
|
3月前
|
数据采集 消息中间件 并行计算
进程、线程与协程:并发执行的三种重要概念与应用
进程、线程与协程:并发执行的三种重要概念与应用
63 0
|
4月前
|
调度 开发者 UED
Kotlin 中的协程是什么?
【8月更文挑战第31天】
278 0
|
6月前
|
存储 Java 调度
Android面试题之Kotlin 协程的挂起、执行和恢复过程
了解Kotlin协程的挂起、执行和恢复机制。挂起时,状态和上下文(局部变量、调用栈、调度器等)被保存;挂起点通过`Continuation`对象处理,释放线程控制权。当恢复条件满足,调度器重新分配线程,调用`resumeWith`恢复执行。关注公众号“AntDream”获取更多并发知识。
134 2