Kotlin 中的 协程 基础篇
一、什么叫协程
协程可以称为轻量级线程,线程代码块;
二、GlobalScope
协程 CoroutineScope (协程作用域) 的上下文中通过 launch、async 等构造器来启动。GlobalScope ,即全局作用域内启动了一个新的协程,这意味这该协程的生命周期只受整个应用程序的生命周期的限制,即只要整个应用程序还在运行中,只要协程的任务还未结束,该协程就可以一直运行。
//在后台启动一个新协程GlobalScope.launch {delay(3000)//非阻塞式延迟println("World!")}println("Hello ")Thread.sleep(4000)//主线程阻塞 4秒,以此保证JVM 存活
输出:
Hello
World!
三、runBlocking
非阻塞代码 delay() 和 阻塞代码 Thread.sleep() ,使得我们很容易就搞混当前程序是否是阻塞的,可以改为 runBlocking 来明确这种情形。
fun test2(){GlobalScope.launch {delay(1000)println("World!")}println("Hello ")runBlocking {delay(2000)}
}
运行结果和第一个程序一样,但是这段代码只使用了非阻塞延迟。主线程调用了 runBlocking 函数,直到 runBlocking 内部的所有协程执行完成后,之后的代码才会继续执行。
可以将以上代码用更喜欢方式重写,使用 runBlicking 来包装 main 函数的执行体:
fun test3() {runBlocking<Unit> {GlobalScope.launch {delay(1000)println("World!")}println("Hello ")delay(2000)}
}
需要注意是,runBlocking 代码块默认运行于其声明所在的线程,而 launch 代码块默认运行于线程池中,可以通过打印当前线程名来进行区分。
fun test3() {runBlocking<Unit> {println(Thread.currentThread().name)GlobalScope.launch {println(Thread.currentThread().name)delay(1000)println("World!")}println("Hello ")delay(2000)}
}
输出:
main // runblocking 运行 main 线程
Hello
DefaultDispatcher-worker-1 //GlobalScope 运行线程池
World!
四、job
延迟一段时间等待另一个协程运行并不是一个好的选择,可以显式(非阻塞的方式)地等待协程执行完成
fun test4() {runBlocking {val job = GlobalScope.launch {delay(1000)print("World!")}println("Hello ")job.join()}
}
现在代码的运行结果仍然是相同,但是主协程与后台作业的持续时间没有任何关系,这样好多了。
五、launch
Launch 函数是 CoroutineScope 的扩展函数,而 runBlocking 的函数体参数也是被声明为 CoroutineScope 的扩展函数,所以 launch 函数就隐式持有了和 runBlicking 相同的协程作用域。此时即使 delay 再久, println("World!") 也一定会被执行。
fun test5() {runBlocking {launch {delay(1000)println("World!")}println("Hello ")}
}
六、CoroutineScope
除了使用官方的几个协程构建器之外,还可以使用 coroutineScope 来声明自己的作用域。 coroutineScope 用于创建一个协程作用域,直到所有启动的子协程都完成后才结束。
RunBlocking 和 coroutineScope 看起来很像,因为它们都是需要等待其它内部所有相同作用域的子协程结束后才会结束自己。两者的主要区别在于 runBlocking 方法会阻塞当前线程,而 coroutineScope 只是挂起并释放底层底层线程以供其他协程使用。由于这个差别,所以 runBlocking 是一个普通函数,而 coroutineScope 是一个挂起函数。
fun test6(){runBlocking {//非阻塞 GlobalScopelaunch {delay(200)println("Task from runBlocking")}//非阻塞 coroutineScope {launch {delay(500)println("Task from nested launch")}delay(100)println("Task from coroutine scope")}println("Coroutine scope is over")}
}
输出:
Task from coroutine scope
Task from runBlocking
Task from nested launch
Coroutine scope is over
六、suspend
suspend 挂起函数可以想常规函数一样在协程中使用,但是它们的额外特性是:可以依次使用其他挂起函数(如delay函数)来使协程挂起。
fun test7() {runBlocking {//内部调用挂起函数,执行耗时任务launch {doWorld()}println("Hello ")}
}suspend fun doWorld() {delay(1000)println("World!")
}
七、repeat
协程是轻量级的
fun test8() {runBlocking {//启动 10万个协程repeat(100_000) { i ->launch {println("I'm sleeping $i ...")delay(500)}}}
}
八、全局协程类似于守护线程
以下代码在 GlobalScope 中启动了一个会长时间运行的协程,它每秒打印两次,然后延迟一段时间后从 mian 函数返回。
fun test9() {runBlocking {GlobalScope.launch {repeat(1000) { i ->println("I'm sleeping $i ...")delay(500)}}delay(1300)}
}
输出:
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
这里由于 launch 函数依附的协程作用域是 GlobalScope,而非 runBlocking 所隐含的作用域。在 GlobalScope 中启动的协程无法使进程保持活动状态,它们像守护线程(当主线程消亡时,守护线程也将消亡)
八、协程代码块默认顺序执行
fun test10() {runBlocking {val time = measureTimeMillis {val one = doSomethingUsefulOne()val two = doSomethingUsefulTwo()println("The answer is ${one + two}")}println("Completed in $time ms")}
}suspend fun doSomethingUsefulOne(): Int {delay(1000)return 13
}suspend fun doSomethingUsefulTwo(): Int {delay(1000)return 29
}
输出:
The answer is 42
Completed in 2011 ms
九、async
async 实现多个协程异步执行,并可以通过 await() 取出结果返回值,launch 类似 async,但是无返回值。
fun test11(){runBlocking {val time = measureTimeMillis {val one = async { doSomethingUsefulOne() }val two = async { doSomethingUsefulTwo() }println("The answer is ${one.await() + two.await()}")}println("Completed in $time ms")}
}
输出:
The answer is 42
Completed in 1019 ms
十、lazy
async 可以设置 CoroutineStart.lazy 为懒加载模式。在这情况下 需要 调用 await() 或者 start() 才启动。
fun test12(){runBlocking {val time = measureTimeMillis {val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }one.start()two.start()println("The answer is ${one.await() + two.await()}")}println("Completed in $time ms")}
}
相关文章:
Kotlin 中的 协程 基础篇
一、什么叫协程 协程可以称为轻量级线程,线程代码块; 二、GlobalScope 协程 CoroutineScope (协程作用域) 的上下文中通过 launch、async 等构造器来启动。GlobalScope ,即全局作用域内启动了一个新的协程,这意味这该协程的生命周期只受整…...
SQL事务
事务的概念: 事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序自动执行。事务就是一些SQL语句组(每条单独的SQL语句也算一个事务),其中事务中的SQL…...
关于flutter中 initState() 与 setState() 用法
initState()函数是在组件渲染之前执行的。在Flutter中,initState()是StatefulWidget的生命周期方法之一,在调用build()方法之前被调用。当创建一个StatefulWidget并将其添加到组件树中时,Flutter会实例化该组件的状态对象,并在调用…...
智能电话机器人是如何自主学习的
电话机器人主要通过语音识别和针对语意的理解识别客户所说的内容,针对性的回答问题,为企业高效筛选意向客户。除了电话机器人语音识别之外,电话机器人能够自主学习,不断完善产品知识及话术等,是它智能的另一种体现。那…...
【Rust】Rust学习 第十八章模式用来匹配值的结构
模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。结合使用模式和 match 表达式以及其他结构可以提供更多对程序控制流的支配权。模式由如下一些内容组合而成: 字面值解构的数组、枚举、结构体或者元组变量通配符占…...
我的学习笔记:数据处理
数据清洗 对数据进行处理和加工,以使其适合分析和建模。数据清洗包括去除重复数据、填补缺失值、处理异常值和转换数据格式等操作,以提高数据的可靠性和准确性,避免数据分析时出现偏差,提高决策的准确性。 数据去重:通…...
GB28181国标平台测试软件NTV-GBC(包含服务器和模拟客户端)
GB28181国标平台测试软件NTV-GBC用于对GB28181国标平台进行测试(测试用例需要服务器软件,服务器软件可以是任何标准的国标平台,我们测试使用的是NTV-GBS),软件实现了设备注册、注销、目录查询,消息订阅、INVITE&#x…...
云原生:重塑企业的技术疆界
云原生技术正在重新塑造我们对软件开发、部署和运维的理解。这些技术带来了灵活性、可扩展性以及在复杂环境中保证稳定性的可能性,这些都是企业在云原生场景中比较关注的问题。本文将主要聚焦于云原生场景,探讨其影响和作用。 云原生的定义 云原生计算基…...
华为星闪,一项将 “ 更稳 WiFi ” 和 “ 更好蓝牙 ” 融合起来的通信标准
兼顾多用途和专业化的 AI 大模型、移除安卓代码的 HarmonyOS NEXT 、给折叠屏应用提供适配方向的《 折叠屏/平板应用体验评估标准 》。。。 不过除了这些比较贴近我们普通用户,容易讲清楚的东西,华为还官宣了一个大家可能没注意的黑科技: 星…...
IDEA创建Mybatis格式XML文件
设置位置:File | Settings | Editor | File and Code Templates 选择Files,点击号 Name中输入xml模板名(名称自行决定),后缀名extension输入xml(固定) 内容处输入Mybatis的xml文件模板内容&…...
二叉树中的最大路径和-递归
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root…...
Python if-else 速记
文章目录 在 Python 中使用三元运算符作为 if-else 速记总结 编程中经常使用速记符号来简化我们的工作。 速记符号是一种可以更简洁、更省时省力地完成工作的方法。 本文将讨论 Python 中使用的速记符号作为 if-else 语句的快捷方式。 在 Python 中使用三元运算符作为 if-else…...
Python使用内置的json模块来处理JSON数据
目录 1、解释说明: 2、使用示例: 3、注意事项: 1、解释说明: 在Python中,我们可以使用内置的json模块来处理JSON数据。这个模块提供了四个主要的函数:dumps、loads、dump、load。 - dumps:将…...
亿赛通电子文档安全管理系统 RCE漏洞
亿赛通电子文档安全管理系统 RCE漏洞 一、 产品简介二、 漏洞概述三、 复现环境四、 漏洞复现小龙POC检测: 五、 修复建议 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失…...
信息安全面试题合集
0x00 前言 本篇会记录一些可能会遇到的面试题,持续更新 0x01 Web SQL注入 sql注入常见的闭合方式有哪些?Mysql5.0上下sql注入有什么区别?SQL注入空格被过滤,有什么绕过方式?过滤了逗号,有什么绕过方式&…...
vue 简单实验 自定义组件 传参数 props
1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"todo-list-app"><todo-item v-bind:todo"todo1"></todo-item> </div> <script> const ListR…...
目标检测笔记(十一):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
文章目录 背景代码结果 背景 由于我们在做项目的时候可能会涉及到某个指定区域进行目标检测或者人脸识别等任务,所以这篇博客是为了探究如何在传统目标检测的基础上来结合特定区域进行检测,以OpenCV自带的包为例。 一般来说有两种方式实现区域指定&…...
PID直观感受简述
0、仿真控制框图 1、增加p的作用(增加响应)P 2、增加I的作用(消除稳差)PI 3、增加D的作用(抑制波动)PID 加入对噪声很敏 4、综合比对...
Tomcat运行后localhost:8080访问自己编写的网页
主要是注意项目结构,home.html放在src/resources/templates下的home.html下,application.properties可以不做任何配置。还有就是关于web包的位置,作者一开始将web包与tabtab包平行,访问8080出现了此类报错: Whitelabel…...
传感网应用开发1+X实训室建方案
一、概述 1.1建设背景 从院校实际教学情况与人才培养计划为出发点,贯彻传感网应用开发1X实训室职业技能等级标准,充分考虑传感网应用开发1X实训室从业人员的职业发展路径与成长路径,以职业素养、职业技能、知识水平为主要框架结构ÿ…...
a16n:实现AI编程助手配置可移植性的插件化转换工具
1. 项目概述:AI编程助手配置的“翻译官”如果你和我一样,同时在使用 Cursor 和 Claude Code 这类 AI 编程工具,那你一定遇到过这个痛点:好不容易在 Cursor 里调教好了一套完美的.cursorrules文件,定义了代码风格、项目…...
本地化AI编码助手codex-assistant:部署、实战与安全指南
1. 项目概述:一个本地化的AI编码助手最近在折腾一个挺有意思的开源项目,叫codex-assistant。简单来说,它就是一个能让你用自然语言直接驱动本地代码任务的工具。想象一下,你对着一个命令行窗口说“给我写个Python函数,…...
绩效考核的量化迷思:如何衡量不可直接测量的技术贡献
一、量化绩效考核的困境:软件测试的“隐形”价值在软件行业的绩效考核体系中,量化指标似乎成了“公平”与“高效”的代名词。代码行数、Bug数量、测试用例覆盖率……这些清晰可统计的数字,被当作衡量技术人员贡献的核心标尺。然而,…...
FanControl完整指南:3步掌握Windows风扇控制,告别噪音烦恼
FanControl完整指南:3步掌握Windows风扇控制,告别噪音烦恼 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/Git…...
逆向工程师的视角:如何用Windbg双机调试分析一个未知Windows驱动(实战案例解析)
逆向工程师的视角:如何用Windbg双机调试分析未知Windows驱动 在安全研究和恶意代码分析领域,逆向工程师常常需要面对未知的Windows驱动程序。这些驱动可能是第三方闭源组件,也可能是潜在的恶意软件载体。与传统的驱动开发调试不同,…...
【信息科学与工程学】【通信工程】第十篇 光通信工程
光通信理论基础、材料基础和算法基础分级分类表 一、理论基础 1. 电磁场理论 麦克斯韦方程组 微分形式、积分形式 本构关系 边界条件 波动方程 亥姆霍兹方程 平面波解 高斯光束 偏振光学 偏振态表示(Jones矢量,Stokes参数) 偏振演化(琼斯矩阵,穆勒矩阵) 双折射…...
C++ 算法实战:从鸡兔同笼到多元方程求解的编程思维演进
1. 从鸡兔同笼开始理解算法思维 记得第一次接触鸡兔同笼问题时,我正啃着铅笔头对着数学作业发愁。题目说笼子里有35个头和94只脚,问鸡和兔各有多少只。这个看似简单的应用题,后来竟成了我算法思维的启蒙老师。 用C解决这个问题时,…...
WarcraftHelper:让魔兽争霸3在现代电脑重获新生的终极解决方案
WarcraftHelper:让魔兽争霸3在现代电脑重获新生的终极解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在Windows …...
3分钟掌握:网易云音乐无损FLAC批量下载终极指南
3分钟掌握:网易云音乐无损FLAC批量下载终极指南 【免费下载链接】NeteaseCloudMusicFlac 根据网易云音乐的歌单, 下载flac无损音乐到本地.。 项目地址: https://gitcode.com/gh_mirrors/nete/NeteaseCloudMusicFlac 还在为无法保存高品质音乐而烦恼吗&#x…...
完整指南:3分钟解锁你的加密音乐文件
完整指南:3分钟解锁你的加密音乐文件 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 你是否曾经遇到过这样的情况:从音乐平台下载的歌曲只能在特定应…...
