Kotlin 协程 (二)

news2025/5/23 4:45:03

Kotlin 协程提供了丰富的功能,能够高效地处理并发和异步任务。以下是对 Kotlin 协程中常见概念和功能的详细讲解,包括它们的定义、作用、使用场景以及最佳实践。


1. 协程核心概念

1.1 CoroutineScope
  • 定义:CoroutineScope 是协程作用域的抽象,用于管理协程的生命周期。它定义了协程的上下文(CoroutineContext),并提供启动协程的方法。
  • 作用
    • 管理协程的生命周期,确保协程在作用域结束时自动取消。
    • 提供结构化并发,便于协程的父子关系管理。
  • 使用场景
    • 在 Android 开发中,用于管理 UI 生命周期内的协程。
    • 在后台任务中,用于批量管理协程。
  • 示例
  val scope = CoroutineScope(Job() + Dispatchers.Default)
  scope.launch {
      // 协程任务
  }
  // 作用域结束时取消所有协程
  scope.cancel()
1.2 Dispatchers
  • 定义:Dispatchers 是协程调度器,用于决定协程在哪个线程上运行。
  • 常见类型
    • Dispatchers.Default:用于计算密集型任务,线程数与 CPU 核心数匹配。适合需要高性能计算的场景。
    • Dispatchers.IO:用于 IO 密集型任务,线程数较多。适合文件读写、网络请求等 IO 操作。
    • Dispatchers.Main:用于 Android 的主线程,处理 UI 更新。适合更新 UI 界面。
  • 示例
  CoroutineScope(Dispatchers.Default).launch {
      // 计算任务
  }
  CoroutineScope(Dispatchers.IO).launch {
      // IO 任务
  }
  CoroutineScope(Dispatchers.Main).launch {
      // UI 更新
  }
1.3 withTimeoutOrNull
  • 定义:withTimeoutOrNull 是一个挂起函数,用于在指定时间内执行协程代码块。如果超时,返回 null 而不抛出异常。
  • 作用
    • 避免因超时导致的异常处理,代码更简洁。
    • 适用于对超时结果不敏感的场景。
  • 使用场景
    • 网络请求:限制请求的最大等待时间。
    • 计算任务:确保长时间计算不会阻塞主线程。
  • 示例
  val result = withTimeoutOrNull(1000L) {
      // 模拟耗时任务
      delay(1200)
      "任务完成"
  }
  println(result) // 输出:null(因为超时)
  

2. 高级协程功能

2.1 并发限制:Semaphore
  • 定义:Semaphore 是一种同步工具,用于控制协程的并发数量。
  • 原理:通过内部计数器管理协程的访问权限,限制同时运行的协程数量。
  • 使用场景
    • 网络请求:限制同时发起的请求数量。
    • 资源管理:防止资源被过度占用。
  • 示例
  val semaphore = Semaphore(10) // 允许最多 10 个协程并发
  repeat(100) {
      semaphore.acquire() // 获取许可
      CoroutineScope(Dispatchers.Default).launch {
          // 并发任务
          semaphore.release() // 释放许可
      }
  }
2.2 异常处理:SupervisorJob
  • 定义:SupervisorJob 是一种特殊的 Job,用于控制协程的取消行为。它允许协程的子任务独立运行,子协程失败不会影响其他子协程。
  • 作用
    • 提供更灵活的异常处理机制。
    • 防止因单个协程失败导致整个任务链中断。
  • 使用场景
    • 在需要容错处理的并发任务中使用。
  • 示例
  val supervisorJob = SupervisorJob()
  val scope = CoroutineScope(supervisorJob + Dispatchers.Default)
  scope.launch {
      // 任务1
      throw Exception("任务1失败")
  }
  scope.launch {
      // 任务2,即使任务1失败也会继续运行
      delay(1000)
      println("任务2完成")
  }
2.3 挂起函数:suspend
  • 定义:suspend 是 Kotlin 协程的关键字,用于定义挂起函数。挂起函数可以在协程中挂起执行,而不会阻塞线程。
  • 作用
    • 简化异步编程,避免回调地狱。
    • 提供类似同步代码的异步逻辑。
  • 使用场景
    • 网络请求、文件读写等异步操作。
  • 示例
  suspend fun fetchData(): String {
      delay(1000) // 模拟耗时操作
      return "数据"
  }

3. 协程调度与生命周期管理

3.1 协程上下文:CoroutineContext
  • 定义:CoroutineContext 是协程的上下文,用于定义协程的运行环境和配置。
  • 组成
    • Job:协程的生命周期管理。
    • CoroutineDispatcher:协程的调度器。
    • CoroutineName:协程名称(调试用)
    • CoroutineExceptionHandler:异常处理器

  • 作用
    • 决定协程的运行方式。
    • 提供统一的配置接口。
  • 示例
  val context = Job() + Dispatchers.Default + CoroutineName("MyCoroutine")
  CoroutineScope(context).launch {
      // 协程任务
  }
3.2 结构化并发
  • 定义:结构化并发是指协程的父子关系管理。父协程可以创建子协程,子协程的生命周期与父协程绑定。
  • 特点
    • 取消 scope 会取消所有子协程
    • 提供结构化的并发管理
    • 常用实现:viewModelScopelifecycleScope
  • 示例
class MyViewModel : ViewModel() {
    fun fetchData() {
        viewModelScope.launch {
            // 自动绑定ViewModel生命周期
        }
    }
}

4. 实践案例与最佳实践

4.1 网络请求
  • 场景:使用协程处理网络请求,避免阻塞主线程。
  • 示例
  val result = withTimeoutOrNull(5000L) {
      // 发起网络请求
      networkRequest()
  }
  result?.let {
      // 处理结果
  } ?: println("请求超时")
4.2 Android 开发
  • 场景:在 Android 中使用协程处理耗时操作,提升用户体验。
  • 示例
  lifecycleScope.launch(Dispatchers.IO) {
      val data = fetchData()
      withContext(Dispatchers.Main) {
          // 更新 UI
      }
  }
4.3 并发任务
  • 场景:限制并发任务的数量,避免资源过度消耗。
  • 示例
  val semaphore = Semaphore(5) // 限制最多 5 个并发任务
  repeat(10) {
      semaphore.acquire()
      CoroutineScope(Dispatchers.Default).launch {
          // 并发任务
          semaphore.release()
      }
  }

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

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

相关文章

[250516] OpenAI 升级 ChatGPT:GPT-4.1 及 Mini 版上线!

目录 ChatGPT 迎来重要更新:GPT-4.1 和 GPT-4.1 mini 正式上线用户如何访问新模型?技术亮点与用户体验优化 ChatGPT 迎来重要更新:GPT-4.1 和 GPT-4.1 mini 正式上线 OpenAI 宣布在 ChatGPT 平台正式推出其最新的 AI 模型 GPT-4.1 和 GPT-4.…

【完整版】基于laravel开发的开源交易所源码|BTC交易所/ETH交易所/交易所/交易平台/撮合交易引擎

功能说明 源码简介与安装环境说明: 开源交易所,基于laravel开发的交易所 | BTC交易所 | ETH交易所 | 交易所 | 交易平台 | 撮合交易引擎。本项目有完整的撮合交易引擎源码、后台管理(后端前端)、前台(交易页面、活动页…

Android Framework学习七:Handler、Looper、Message

文章目录 简介LooperMessageMessageQueueHandlerFramework学习系列文章 简介 Looper当做一台传送装置,MessageQueue是传送带,传送带上放的是Message,Handler用于发送Message分发与接收处理。 Looper frameworks/base/core/java/android/app…

MyBatis:简化数据库操作的持久层框架

1、什么是Mybatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由 apachesoftwarefoundation 迁移到了google code,由谷歌托管,并且改名为MyBatis 。 2013年11月迁移到Github。 iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框…

【001】RenPy打包安卓apk 流程源码级别分析

1. 入口在下图 2. SDK版本及代码入口 (renpy-8.3.7-sdk) 由于SDK一直在升级,本文采用 标题中的版本进行分析,整体逻辑变化不太大。 实际执行逻辑是调用的rapt 2.1 点击按钮实际执行逻辑 def AndroidIfState(state, needed, acti…

物理信息神经网络(PINNs)在悬臂梁分析中的应用研究

一、引言 物理信息神经网络(Physics-Informed Neural Networks, PINNs)是近年来兴起的一种结合深度学习与传统物理建模的创新方法。本文将探讨PINNs在悬臂梁力学分析中的应用,展示如何利用这一技术解决工程力学中的经典问题。 二、PINNs基本原理 PINNs的核心思想是…

论文浅尝 | HOLMES:面向大语言模型多跳问答的超关系知识图谱方法(ACL2024)

笔记整理:李晓彤,浙江大学硕士,研究方向为大语言模型 论文链接:https://arxiv.org/pdf/2406.06027 发表会议:ACL 2024 1. 动机 多跳问答(Multi-Hop Question Answering, MHQA)技术近年来在自然语…

jenkins使用Send build artifacts over SSH发布jar包目录配置

本测试用ruoyi-plus的代码。 1 [GitLab 自动触发 Jenkins 构建_jenkins构建触发器没有build when a change is pushed to git-CSDN博客](https://blog.csdn.net/wangyiyungw/article/details/81776972) 2 [jenkins使用Send build artifacts over SSH遇到的坑-CSDN博客](https…

uni-app小程序登录后…

前情 最近新接了一个全新项目,是类似商城的小程序项目,我负责从0开始搭建小程序,我选用的技术栈是uni-app技术栈,其中就有一个用户登录功能,小程序部分页面是需要登录才可以查看的,对于未登录的用户需要引…

【深度学习基础】从感知机到多层神经网络:模型原理、结构与计算过程全解析

【深度学习基础】从感知机到多层神经网络:模型原理、结构与计算过程全解析 1. 引言 神经网络的重要性: 作为人工智能的核心技术之一,神经网络通过模拟人脑神经元的工作机制,成为解决复杂模式识别、预测和决策任务的利器。从图像分…

解决Power BI Desktop导入Excel数据第一行不是列标题问题

选中第一行不是列标题的表→鼠标右键→选择编辑查询→进入Power Query界面→点击“将第一行用作标题”→点击左边的“关闭并应用” 第一行就提升为标题了

springboot3.x只需两步快速整合nacos作配置中心

一、下载依赖 我在网上找了各种资料&#xff0c;都是要先确定springcloud版本&#xff0c;实际操作却可能由于版本或者镜像或者maven等问题报红&#xff0c;出现各种情况。 实际只需要指定特定版本号就行&#xff0c;添加下面两个依赖 <dependency><groupId>com.…

<uniapp><vuex><状态管理>在uniapp中,如何使用vuex实现数据共享与传递?

前言 本专栏是基于uniapp实现手机端各种小功能的程序&#xff0c;并且基于各种通讯协议如http、websocekt等&#xff0c;实现手机端作为客户端&#xff08;或者是手持机、PDA等&#xff09;&#xff0c;与服务端进行数据通讯的实例开发。 发文平台 CSDN 环境配置 系统&…

数据湖和数据仓库的区别

在当今数据驱动的时代&#xff0c;企业需要处理和存储海量数据。数据湖与数据仓库作为两种主要的数据存储解决方案&#xff0c;各自有其独特的优势与适用场景。本文将客观详细地介绍数据湖与数据仓库的基本概念、核心区别、应用场景以及未来发展趋势&#xff0c;帮助读者更好地…

【论文阅读 | AAAI 2025 | FD2-Net:用于红外 - 可见光目标检测的频率驱动特征分解网络】

论文阅读 | AAAI 2025 | FD2-Net&#xff1a;用于红外 - 可见光目标检测的频率驱动特征分解网络 1.摘要&&引言2. 方法2.1总体架构2.2特征分解编码器2.3多模态重建机制2.4训练损失 3.实验3.1实验设置3.2主要结果3.3消融研究 4.结论 题目&#xff1a;FD2-Net: Frequency-…

济南国网数字化培训班学习笔记-第三组-1-电力通信传输网认知

电力通信传输网认知 电力通信基本情况 传输介质 传输介质类型&#xff08;导引与非导引&#xff09; 导引传输介质&#xff0c;如电缆、光纤&#xff1b; 非导引传输介质&#xff0c;如无线电波&#xff1b; 传输介质的选择影响信号传输质量 信号传输模式&#xff08;单工…

OAT 初始化时出错?问题可能出在 PAM 配置上|OceanBase 故障排查实践

本文作者&#xff1a;爱可生数据库工程师&#xff0c;任仲禹&#xff0c;擅长故障分析和性能优化。 背景 某客户在使用 OAT 初始化OceanBase 服务器的过程中&#xff0c;进行到 precheck 步骤时&#xff0c;遇到了如下报错信息&#xff1a; ERROR - check current session ha…

1-机器学习的基本概念

文章目录 一、机器学习的步骤Step1 - Function with unknownStep2 - Define Loss from Training DataStep3 - Optimization 二、机器学习的改进Q1 - 线性模型有一些缺点Q2 - 重新诠释机器学习的三步Q3 - 机器学习的扩展Q4 - 过拟合问题&#xff08;Overfitting&#xff09; 一、…

Hass-Panel - 开源智能家居控制面板

文章目录 ▎项目介绍&#xff1a;预览图▎主要特性安装部署Docker方式 正式版Home Assistant Addon方式详细安装方式1. Home Assistant 插件安装&#xff08;推荐&#xff09;2. Docker 安装命令功能说明 &#xff1a;3. Docker Compose 安装升级说明Docker Compose 版本升级 功…

Ubuntu搭建NFS服务器的方法

0 工具 Ubuntu 18.041 Ubuntu搭建NFS服务器的方法 在Ubuntu下搭建NFS&#xff08;网络文件系统&#xff09;服务器可以让我们像访问本地文件一样访问Ubuntu上的文件&#xff0c;例如可以把开发板的根文件系统放到NFS服务器目录下方便调试。 1.1 安装nfs-kernel-server&#…