当前位置: 首页 > news >正文

【Kotlin 】协程

Kotlin协程

  • 背景
  • 定义
  • 实践
    • GlobalScope.launch
    • runBlocking
    • 业务实践

背景

在项目实践过程中,笔者发现很多异步或者耗时的操作,都使用了Kotlin中的协程,所以特地研究了一番。

定义

关于协程(Coroutine),其实更多的应该是一种并发设计模式。与传统的线程或进程相比,协程更加轻量级,因为它运行在线程之上,在执行过程中可以主动地暂停,并在需要时恢复执行。而且这些切换操作是在操作系统中的用户态完成的。

实践

  • 引入maven依赖:
<dependency><groupId>org.jetbrains.kotlinx</groupId><artifactId>kotlinx-coroutines-core</artifactId>
</dependency>
  • 两种启动模式
    • runBlocking
    • GlobalScope.launch

GlobalScope.launch

GlobalScope.launch 中启动的协程不会阻塞主线程。主线程会继续执行,而协程会在后台执行。在上述例子中,为了演示效果,使用了 Thread.sleep(2000) 来模拟等待协程执行。
其中,launch 是一个函数,用于创建协程并将其函数主体的执行分派给相应的调度程序。

fun main() {// 启动协程GlobalScope.launch {delay(2000) // 挂起协程,模拟异步操作println("World!")}println("Hello,")Thread.sleep(4000) // 阻塞主线程,等待协程执行完毕
}

runBlocking

runBlocking 中启动的协程会阻塞当前线程,直到所有启动的协程都执行完毕。

fun main() = runBlocking {// 在 runBlocking 作用域内启动协程launch {// 协程代码println("Inside coroutine")}// 主线程继续执行println("Outside coroutine")// 阻塞主线程,等待协程执行完毕
}

业务实践

  • Dispatchers.IO Kotlin提供的协程调度方式,指示此协程应在为 I/O 操作预留的线程上执行,适合在主线程之外执行磁盘或网络 I/O。
  • Dispatchers.Main 使用此调度程序可在主线程上运行协程。(在官方文档介绍中,主要用于安卓开发中,与界面交互和执行快速工作。)
  • Dispatchers.Default 适合在主线程之外执行占用大量 CPU 资源的工作。
private fun sendRefundHttpPost(weChatPayRefundUrl: String, xmlRequestData: String): Map<String, String> = runBlocking {// 启用协程发送退款操作return@runBlocking withContext(Dispatchers.IO) {val responseXmlStr = careWeChatHttps.postXmlForString(weChatPayRefundUrl, xmlRequestData)WXPayUtil.xmlToMap(responseXmlStr)}}
 private fun getSchoolDate(allTeacherIds: Set<String>): WildSchoolData = runBlocking {// 涉及统计的allTeacherIds 数量比较大, 创建异步任务去操作val elements = allTeacherIds.chunked(60).map {async(Dispatchers.Default) {val totalCount = teacherPerformanceServiceApi.getTeachersTotalPerformanceCount(it).performanceCountval currentWeekCount = teacherPerformanceServiceApi.getTeachersCurrentWeekPerformanceCountByByRangeTime(it).performanceCountWildSchoolData(totalCount, currentWeekCount)}}// 调用await等待异步任务结束return@runBlocking WildSchoolData(elements.awaitAll().sumBy { it.totalCount }, elements.awaitAll().sumBy { it.currentWeekCount })}
fun savePoint(pagePointVo: PagePointVo): Any {// 启用协程执行一个操作流水的插入, 不影响其他操作GlobalScope.launch(context = Dispatchers.IO) {val pagePoint = PagePoint().apply {this.schoolId = pagePointVo.schoolIdthis.userId = pagePointVo.userIdthis.userRole = pagePointVo.userRolethis.moduleKey = pagePointVo.moduleKeythis.eventId = pagePointVo.eventIdthis.clickTime = Date()}pagePointMapper.insert(pagePoint)}// 其他操作}
http://www.lryc.cn/news/270800.html

相关文章:

  • 用Xshell连接虚拟机的Ubuntu20.04系统记录。虚拟机Ubuntu无法上网。本机能ping通虚拟机,反之不能。互ping不通
  • 人机对话--关于意识机器
  • 八股文打卡day16——计算机网络(16)
  • Java Object浅克隆深克隆
  • 概率的 50 个具有挑战性的问题 [8/50]:完美的桥牌
  • 自动驾驶学习笔记(二十四)——车辆控制开发
  • 【起草】【第十二章】定制ChatGPT数字亲人
  • MySQL数据库索引
  • 【LLM 】7个基本的NLP模型,为ML应用程序赋能
  • 数字人私人定制
  • CollectionUtils
  • 很想写一个框架,比如,spring
  • Java集合/泛型篇----第五篇
  • ACES 增强版不丹水稻作物地图(2016-2022 年)
  • 【Spark精讲】一文讲透Spark宽窄依赖的区别
  • nacos2.3.0配置中心问题处理
  • Apollo自动驾驶系统:实现城市可持续交通的迈向
  • 【WPF.NET开发】附加事件
  • java浅拷贝BeanUtils.copyProperties引发的RPC异常 | 京东物流技术团队
  • 【pynput】鼠标行为追踪并模拟
  • docker小白第十天
  • Apache SSI 远程命令执行漏洞
  • 阿里云30个公共云地域、89个可用区、5个金融云和政务云地域
  • Linux驱动开发之杂项设备注册和Linux2.6设备注册
  • javafx写一个文档编辑器
  • PHP与Angular详细对比 帮助你选择合适的项目技术
  • 基于立锜RTQ7882,支持全协议及DP显示功能的PD快充方案
  • 2023-12-25 LeetCode每日一题(不浪费原料的汉堡制作方案)
  • JavaScript 基础通关
  • 目标检测损失函数:IoU、GIoU、DIoU、CIoU、EIoU、alpha IoU、SIoU、WIoU原理及Pytorch实现