Kotlin 协程 (一)

1. Kotlin 协程的核心概念

1.1 协程(Coroutine)
  • 定义:协程是一种轻量级的执行上下文,可以在任何时候挂起和恢复,而不需要阻塞线程。
  • 特点
    • 比传统线程更轻量,开销更小。
    • 支持挂起和恢复,避免了阻塞线程和资源浪费。
    • 提供更简洁的并发编程方式。
1.2 挂起函数(Suspend Function)
  • 定义:使用 suspend 关键字修饰的函数,可以在协程中挂起执行,挂起期间不会阻塞线程。
  • 作用:允许协程在等待任务完成时释放线程资源,待任务完成后恢复执行。
1.3 协程作用域(Coroutine Scope)
  • 定义:协程作用域定义了协程的生命周期,确保协程在作用域结束时被取消。
  • 常见作用域
    • GlobalScope:全局作用域,生命周期与整个应用程序一致(不推荐用于实际开发)。
    • CoroutineScope:自定义作用域,可通过 CoroutineScope(Dispatchers) 创建。
    • runBlocking:用于测试场景,会阻塞当前线程直到协程完成。
1.4 协程构建器(Coroutine Builders)
  • launch:启动一个协程,不返回结果。
  • async:启动一个协程,并返回一个 Deferred 对象,可用于获取结果。
  • runBlocking:阻塞当前线程,直到协程完成(仅用于测试)。

2. Kotlin 协程的使用方法

以下是协程使用的基本步骤:

2.1 添加依赖项

在项目的 build.gradle 文件中添加 Kotlin 协程库依赖:

dependencies {implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'
}
2.2 创建协程作用域

协程必须在协程作用域中运行。例如:

import kotlinx.coroutines.*fun main() = runBlocking { // 用于测试,实际开发中避免使用val scope = CoroutineScope(Dispatchers.Default)scope.launch {// 在这里执行异步任务}
}
2.3 启动协程

使用 launch 或 async 启动协程:

  • launch:用于不需要返回结果的异步任务。
  • async:用于需要返回结果的异步任务。
scope.launch {delay(1000L) // 模拟耗时操作println("异步任务完成")
}val deferred = scope.async {delay(1000L)"异步任务结果"
}
println("异步任务返回值: ${deferred.await()}")
2.4 使用挂起函数

挂起函数允许协程在等待任务时挂起,例如 delay

suspend fun fetchData(): String {delay(1000L) // 模拟网络请求return "Data fetched"
}

3. Kotlin 协程的具体示例

以下通过几个常见场景展示协程的实际用法。

3.1 简单的异步任务

使用 launch 启动一个异步任务:

import kotlinx.coroutines.*fun main() = runBlocking {launch {delay(1000L)println("World!")}println("Hello,")
}输出:
Hello,
World!
3.2 并行任务与结果获取

使用 async 和 await 实现并行任务:

import kotlinx.coroutines.*fun main() = runBlocking {val deferred1 = async {fetchDataFromNetwork1()}val deferred2 = async {fetchDataFromNetwork2()}println("Data1: ${deferred1.await()}")println("Data2: ${deferred2.await()}")
}suspend fun fetchDataFromNetwork1(): String {delay(1000L)return "NetworkData1"
}suspend fun fetchDataFromNetwork2(): String {delay(1000L)return "NetworkData2"
}
3.3 取消协程

使用 cancel 方法取消协程:

import kotlinx.coroutines.*fun main() = runBlocking {val job = launch {delay(5000L)println("Task completed")}delay(1000L)job.cancel()println("Coroutine cancelled")
}

4.实际应用示例

网络请求与数据库操作

// 假设有以下挂起函数
suspend fun fetchUserData(): UserData = withContext(Dispatchers.IO) {// 模拟网络请求delay(1000)UserData("John", 30)
}suspend fun saveToDatabase(user: UserData) = withContext(Dispatchers.IO) {// 模拟数据库操作delay(500)println("User saved: $user")
}data class UserData(val name: String, val age: Int)fun main() = runBlocking {// 顺序执行val user = fetchUserData()saveToDatabase(user)// 并发执行多个网络请求val users = listOf("user1", "user2", "user3")val deferredList = users.map { userId ->async { fetchUserDataForId(userId) }}val results = deferredList.awaitAll()println("All users fetched: $results")
}suspend fun fetchUserDataForId(userId: String): UserData {delay(1000)return UserData("$userId-Name", 20 + userId.last().digitToInt())
}

5. 总结

  • 核心概念:协程、挂起函数、协程作用域和协程构建器是协程编程的基础。
  • 使用方法:通过添加依赖、创建作用域、启动协程和使用挂起函数,可以轻松实现异步编程。
  • 适用场景:协程适用于网络请求、文件 IO、CPU 密集型任务等需要并发处理的场景。

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

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

相关文章

机器学习 集成学习方法之随机森林

集成学习方法之随机森林 1 集成学习2 随机森林的算法原理2.1 Sklearn API2.2 示例 1 集成学习 机器学习中有一种大类叫集成学习(Ensemble Learning),集成学习的基本思想就是将多个分类器组合,从而实现一个预测效果更好的集成分类…

thinkphp6实现统一监听并记录所有执行的sql语句除查询外

创建文件app/middleware/SqlLogger.php <?php namespace app\middleware;use think\facade\Db; use think\facade\Session;class SqlLogger {public function handle($request, \Closure $next){// 监听所有SQL $request->ip()Db::listen(function($sql, $time) {if (p…

pytorch训练可视化工具---TensorBoard

一、目的&#xff1a;为什么使用 TensorBoard 调控模型 使用 TensorBoard 可以帮我们&#xff1a; 实时查看 loss / acc 曲线 → 判断是否过拟合、欠拟合&#xff1b; 对比不同模型或超参数的效果&#xff1b; 可视化模型结构 → 帮助调试模型设计&#xff1b; 查看权重/梯…

机器学习知识自然语言处理入门

一、引言&#xff1a;当文字遇上数学 —— 自然语言的数字化革命 在自然语言处理&#xff08;NLP&#xff09;的世界里&#xff0c;计算机要理解人类语言&#xff0c;首先需要将文字转化为数学向量。早期的 One-Hot 编码如同给每个词语分配一个唯一的 “房间号”&#xff0c;例…

Linux-线程概念和控制

1.Linux线程概念 1.1什么是线程 • 在⼀个程序⾥的⼀个执⾏路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“⼀个进程内部 的控制序列” • ⼀切进程⾄少都有⼀个执⾏线程 • 线程在进程内部运⾏&#xff0c;本质是在进程地址空间内运⾏…

【氮化镓】低剂量率对GaN HEMT栅极漏电的影响

2024 年 2 月 22 日,中国科学院新疆理化技术研究所的Li等人在《IEEE ACCESS》期刊发表了题为《Degradation Mechanisms of Gate Leakage in GaN-Based HEMTs at Low Dose Rate Irradiation》的文章,基于实验分析和 TCAD 仿真,研究了低剂量率辐照下基于 GaN 的 p 型栅高电子迁…

.NET Core 中 Swagger 配置详解:常用配置与实战技巧

随着微服务架构和 RESTful API 的广泛应用&#xff0c;API 文档的管理和自动化生成成为了开发中的重要部分。Swagger&#xff08;现为 OpenAPI&#xff09;是一款功能强大的工具&#xff0c;它可以自动生成 API 文档&#xff0c;并提供交互式 UI&#xff0c;帮助开发者、测试人…

海康工业相机白平衡比选择器对应的值被重置后,如何恢复原成像

做项目的时候&#xff0c;有时候手抖&#xff0c;一不小心把一个成熟稳定的项目的相机配置&#xff0c;重置了&#xff0c;如何进行恢复呢&#xff0c;在不知道之前配置数据的情况下。 我在做项目的时候&#xff0c;为了让这个相机成像稳定一点&#xff0c;尤其是做颜色检测时…

【八股战神篇】Java虚拟机(JVM)高频面试题

目录 专栏简介 一 请解释Java虚拟机(JVM)及其主要功能 延伸 1. JVM的基本概念 2. JVM的主要功能 二 对象创建的过程了解吗 延伸 1.Java 创建对象的四种常见方式 三 什么是双亲委派模型 延伸 1.双亲委派机制的作用: 2.双亲委派模型的核心思想: 3.双亲委派模型的…

win10 上删除文件夹失败的一个原因:sqlYog 备份/导出关联了该文件夹

在尝试删除路径为.../bak/sql的文件时&#xff0c;系统提示无权限操作。然而&#xff0c;关闭SQLyog后&#xff0c;删除操作成功完成。这表明SQLyog可能正在占用该文件&#xff0c;导致删除权限受限。关闭SQLyog后&#xff0c;文件被释放&#xff0c;删除操作得以顺利进行。建议…

Oracle中如何解决LATCH:CACHE BUFFERS LRU CHAIN

简单来讲&#xff0c;Oracle为了高效管理BUFFER CACHE主要使用以下2种LRU列&#xff1a; LRU列&#xff0c;又叫替换列&#xff08;replacement list&#xff09;&#xff0c;其中又分为主列和辅助列。 主列&#xff1a;已使用的缓冲区列&#xff0c;分为HOT和COLD区域。HOT区…

C++:迭代器

迭代器的本质&#xff1a;对象。 迭代器与指针类似&#xff0c;通过迭代器可以指向容器中的某个元素&#xff0c;还可以对元素进行操作。 迭代器统一规范了遍历方式。不同的数据结构可以用统一的方式去遍历。 接下来是一个自定义迭代器的代码示例。 #include<iostream&g…

(4)Java虚拟线程与传统线程对比

虚拟线程与传统线程对比 &#x1f504; &#x1f4cb; 核心问题 Project Loom的虚拟线程与传统线程在资源消耗上有何区别&#xff1f;如何设计一个支持百万级并发的服务&#xff1f; &#x1f4ca; 资源消耗比较 &#x1f418; 传统线程 &#x1f4cf; 每线程约1MB栈空间&am…

Java 单元测试框架比较:JUnit、TestNG 哪个更适合你?

Java 单元测试框架比较&#xff1a;JUnit、TestNG 哪个更适合你&#xff1f; 在 Java 开发领域&#xff0c;单元测试是保证代码质量的重要环节。而选择一个合适的单元测试框架&#xff0c;对于提升测试效率和代码可靠性至关重要。本文将深入比较 JUnit 和 TestNG 这两个主流的…

从零开始的抽奖系统创作(2)

我们接着进行抽奖系统的完善。 前面我们完成了 1.结构初始化&#xff08;统一结果返回之类的&#xff0c;还有包的分类&#xff09; 2.加密&#xff08;基于Hutool进行的对称与非对称加密&#xff09; 3.用户注册 接下来我们先完善一下结构&#xff08;统一异常处理&#…

【vs2022的C#窗体项目】打开运行+sql Server改为mysql数据库+发布

1. vs2022打开运行原sql Server的C#窗体项目更改为mysql数据库 1.1. vs2022安装基础模块即可 安装1️⃣vs核心编辑器2️⃣.net桌面开发必选&#xff0c;可选均不安装&#xff01;&#xff01;&#xff01; 为了成功连接mysql数据库&#xff0c;需要安装组件NuGet包管理器 安…

AI 编程 “幻觉” 风险频发?飞算 JavaAI 硬核技术筑牢安全防线

AI 技术已深度融入编程领域&#xff0c;为开发者带来前所未有的便利与效率提升。然而&#xff0c;AI 编程 “幻觉” 问题如影随形&#xff0c;频频引发困扰&#xff0c;成为阻碍行业稳健发展的潜在风险。飞算 JavaAI 凭借一系列硬核技术&#xff0c;强势出击&#xff0c;为攻克…

数据库----软考中级软件设计师(自用学习笔记)

目录 1、E-R图 2、结构数据模型 3、数据库的三级模式结构 4、关系代数 5、查询 6、SQL控制语句 7、视图​编辑 8、索引 9、关系模式 10、函数依赖 11、通过闭包求候选码 12、范式 13、无损连接和保持函数依赖 14、数据库设计 15、数据库的控制功能 16、数据库…

【Qt】Qt常见控件的相关知识点

1.close退出槽函数 2.设置快捷键&#xff0c;QMenu 。 适用&字母就能设置快捷键&#xff0c;运行qt程序&#xff0c;最后就可以按Alt对应的字母进行快捷操作。 3.QMenuBar内存泄露问题 如果ui已经自动生成了menubar&#xff0c;我们再次生成一个新的菜单栏&#xff0c;而…

httpx[http2] 和 httpx 的核心区别及使用场景如下

httpx[http2] 和 httpx 的核心区别在于 HTTP/2 协议支持&#xff0c;具体差异及使用场景如下&#xff1a; 1. 功能区别 命令/安装方式协议支持额外依赖适用场景pip install httpx仅 HTTP/1.1无通用请求&#xff0c;轻量依赖pip install httpx[http2]支持 HTTP/2需安装 h2>3…