协程的八种创建方式

news2024/9/23 11:19:51

在这里插入图片描述

协程简介

在深入了解创建方式之前,我们先简要回顾一下协程是什么。协程是轻量级的线程。它们在协作式多任务处理中运行,允许在不阻塞线程的情况下挂起和恢复。这使得协程非常适合进行异步编程和高性能的并发任务。🌐

Kotlin中创建协程的方式

Kotlin提供了多种方式来创建协程,每种方式都适用于不同的场景和需求。下面我们将一一探讨。

1. 使用launch函数

launch是最常用的创建协程的方法。它在CoroutineScope的上下文中启动一个新的协程。以下是使用launch函数的一个基本示例:

import kotlinx.coroutines.*

fun main() {
 val scope = CoroutineScope(Dispatchers.Default)
 scope.launch {
     println("This is run in a coroutine")
 }
}

在上面的示例中,launch函数创建了一个协程,该协程在Dispatchers.Default调度器上执行,通常用于CPU密集型任务。👨‍💻

2. 使用asyncawait

async函数与launch类似,但它返回一个Deferred对象,该对象是一个轻量级的非阻塞future,表示一个可能尚未完成的异步计算。async常用于需要并发计算结果的场景。一旦协程完成,可以使用await方法获取结果。这是一个示例:

import kotlinx.coroutines.*

fun main() {
 val scope = CoroutineScope(Dispatchers.Default)
 val deferredResult = scope.async {
     delay(1000L) // 模拟异步任务
     return@async "Result from coroutine"
 }
 runBlocking {
     println("Waiting for result...")
     val result = deferredResult.await()
     println("Received result: $result")
 }
}

上面的代码展示了如何使用async启动一个协程,并在其完成时使用await获取结果。📦

3. 使用runBlocking

runBlocking是一个特殊的协程构建器,它会阻塞当前线程来等待协程完成。这通常不推荐在生产代码中使用,但它对于测试和一次性的任务非常有用,尤其是在需要从协程中直接返回结果时。下面是一个使用runBlocking的示例:

import kotlinx.coroutines.*

fun main() {
 println("Before runBlocking")
 runBlocking {
     delay(1000L) // 模拟耗时任务
     println("Inside runBlocking")
 }
 println("After runBlocking")
}

上面的示例展示了runBlocking如何在协程内部执行任务,同时阻塞主线程直到协程执行完毕。🚦

4. 使用coroutineScope

coroutineScope是另一个协程构建器,它创建一个新的协程作用域,并且只有当所有在这个作用域内启动的协程都完成时,才会继续向下执行。这对于在并发程序中进行结构化并发非常有用。示例如下:

import kotlinx.coroutines.*

suspend fun performTask() {
 coroutineScope { // 创建一个协程作用域
     launch {
         delay(1000L)
         println("Task 1 completed")
     }
     launch {
         delay(1000L)
         println("Task 2 completed")
     }
     println("coroutineScope will wait for all children to complete")
 }
 println("All children are complete")
}

fun main() {
 runBlocking {
     performTask()
 }
}

在上述代码中,performTask函数中的coroutineScope确保所有启动的协程(两个launch)都执行完成后,才会打印最后的消息。🔗

5. 使用supervisorScope

supervisorScopecoroutineScope相似,但它有一个关键的区别:在supervisorScope中,一个子协程的失败不会导致其他子协程的取消。这非常适合那些子任务可能相互独立且一个任务的失败不应该影响其他任务的场景。示例如下:

import kotlinx.coroutines.*

suspend fun performSupervisedTask() {
 supervisorScope {
     val childOne = launch {
         println("Child one is running")
         throw Exception("Child one failure")
     }
     val childTwo = launch {
         delay(1000L)
         println("Child two is running")
     }
     try {
         childOne.join()
         childTwo.join()
     } catch (e: Exception) {
         println("Caught an exception from child one: ${e.message}")
     }
 }
}

fun main() {
 runBlocking {
     performSupervisedTask()
 }
}

在这个示例中,尽管childOne抛出了一个异常,但childTwo仍然能够继续执行。这是supervisorScope的主要优势。🛡️

6. 使用lifecycleScope

在Android开发中,lifecycleScope是专门为处理与生命周期绑定的协程而设计的。这个作用域自动与Activity或Fragment的生命周期绑定,确保协程在Lifecycle所有者(如Activity或Fragment)销毁时自动取消。这种方式非常适合用于UI相关的任务,如网络请求或数据库操作。以下是一个例子:

import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.*

fun MainActivity.someFunction() {
 lifecycleScope.launch {
     delay(1000L) // 模拟耗时操作
     updateUI() // 更新UI
 }
}

fun updateUI() {
 // 更新UI的代码
}

在这个示例中,协程在MainActivitylifecycleScope中启动,确保如果MainActivity被销毁,协程也会相应地被取消。🏠

7. 使用viewModelScope

viewModelScope是绑定到Android的ViewModel的生命周期的。这个作用域确保协程只在ViewModel存活期间活动,并在ViewModel清除时自动取消所有协程。这对于处理需要在用户界面与后端之间进行长时间运行操作的应用程序非常有用。示例如下:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*

class MyViewModel : ViewModel() {
 fun performNetworkOperation() {
     viewModelScope.launch {
         val data = networkCall() // 网络请求
         processData(data) // 处理数据
     }
 }

 suspend fun networkCall(): String {
     delay(1000L) // 模拟网络延迟
     return "Network data"
 }

 fun processData(data: String) {
     // 处理接收到的数据
 }
}

在这个示例中,MyViewModel中的协程是在viewModelScope内部启动的,这意味着只要ViewModel未被清除,协程就可以安全地执行。🔍

8. 使用GlobalScope

GlobalScope是一个全局协程作用域,它的生命周期只受整个应用程序的生命周期限制。使用GlobalScope启动的协程在应用程序的任何部分都可以运行,且只会在应用程序完全停止时才会被取消。尽管它在某些情况下看起来很方便,但通常不推荐使用GlobalScope,因为它可能会导致内存泄漏和其他生命周期问题。示例代码如下:

import kotlinx.coroutines.*

fun performGlobalOperation() {
 GlobalScope.launch {
     delay(5000L) // 模拟长时间运行的任务
     println("Global scope operation")
 }
}

在这个示例中,即使用户离开了启动这个协程的界面,协程仍将继续执行,直到任务完成。🌍

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

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

相关文章

IDA相关

IDA相关 IDA pro 7.7 链接: https://pan.baidu.com/s/14F0M1lxZMCoCAmR3AFmm-A?pwdjk14 提取码: jk14 lazy ida https://github.com/P4nda0s/LazyIDA pip install yara pip install keystone24.0.0.0 可以把ida目录里python site-package的内容复制到本机python的lib/si…

html写table表格,后端数据中涉及到身份证号或者电话号的情况,生成excel变成1+e17或者###等类似的加密或科学计数法情况

效果展示(对比图): 原: 新: 解决办法: 加以下样式即可展示原来的 style"vnd.ms-excel.numberformat:" 如若想知道…

链表的实现(C++版)

对于链表的学习,之前在C语言部分的时候就已经有学习过,也学会了使用C语言来打造一个链表.如今学了C 则想通过C来打造一个链表,以达到锻炼自己的目的. 1.链表的初步实现 1.节点模板的设置 template <class T> struct ListNode{ListNode <T>* _next;ListNode <T…

【Linux 网络】应用层

文章目录 应用层协议序列化的概念jsoncpp 1. HTTP1.1URLURL编解码 1.2 HTTP的格式HTTP请求格式HTTP响应格式 1.3 HTTP的方法GET/POST 1.4 HTTP的状态码1.5 HTTP的报头cookie和session1.6 简单HTTP服务器 2. HTTPS2.1 加密方式对称加密非对称加密全对称加密混合加密密钥协商对称…

CSS画箭头

向右示例 .arrows {height: 7px;width: 7px;background-color: transparent;border-top: 2px solid rgba(0, 0, 0, 0.3);border-right: 2px solid rgba(0, 0, 0, 0.3);transform: rotate(45deg);margin-left: 6px; } 可以尝试将其封装为组件&#xff08;以微信小程序为例&…

上位机《1》 步进电机、步进驱动器,连接端子(接线盒子)等

正运动技术 固高控制卡 雷赛控制卡 步进电机 电机内部的线圈数不同&#xff0c;组成的电机相数也不同&#xff0c;两相步进电机电机内部是由2个线圈组成&#xff0c;而三相步进电机内部是由3个线圈。 相数越多&#xff0c;步进角越小。所有精度就越高。步进电机转速越快&…

经验分享:大数据多头借贷风险对自身的不利影响?

在现代金融体系中&#xff0c;大数据技术的应用使得多头借贷成为一种普遍现象。多头借贷指的是个人或企业在短时间内同时或近期内申请多笔贷款或信用产品&#xff0c;这种行为可能带来一系列财务和信用风险。以下是大数据多头借贷风险对个人自身可能产生的不利影响&#xff1a;…

花了2小时,自己做了一个出入库系统

出入库管理是库存管理工作的重中之重&#xff0c;但在刚做产品出入库时&#xff0c;我可是踩了不少坑—— 库存管理不精确仓库作业效率低下货物追踪困难报表统计繁琐... 后来我就自学了下&#xff0c;花了两个小时自己做了一套织信出入库管理系统&#xff0c;全程没有敲一个代…

帆软10.0报表部署到正式环境后,不显示数据集的数据。

修改正式环境的数据连接 1&#xff09;数据连接的「编码」类型设置为「默认」。 2&#xff09;数据连接的「数据连接URL」后加后缀&#xff0c;如下图所示。格式为&#xff1a; jdbc:mysql://hostname:port/database?generateSimpleParameterMetadatatrue&useUnicodetru…

运维工程师,刚入职一个之前没有运维的公司,该做什么?

运维工程师&#xff0c;刚入职一个之前没有运维的公司&#xff0c;该做什么&#xff1f; 下面内容&#xff0c;只谈技术工作方面的&#xff0c;人情世故的方面自己体会吧。。。。 前言 写这个&#xff0c;主要是有一个朋友&#xff0c;也是运维工程师&#xff0c;五年以上运…

【STL】之 list 使用方法和模拟实现

目录 前言&#xff1a; list是什么&#xff1f; 节点类 迭代器类&#xff1a; list类 list的迭代器失效问题 前言&#xff1a; 之前我们分别手撕了string类和vector类&#xff0c;今天我们来跟list类打打交道~ list是什么&#xff1f; 通过查c文档可知&#xff0c;list…

(2)基于巴法云+MQTT+微信小程序控制esp8266点灯

目录 1、wifi配置指令表 2、连接连接wifi网络 3、连接巴法云MQTT &#xff08;1&#xff09;配置用户属性ATMQTTUSERCFG ① 命令格式&#xff1a; ② 命令参数&#xff1a; ③ 实际配置方式&#xff1a; &#xff08;2&#xff09;配置ESP 设备连接的 MQTT broker ① 命令格式…

【AI大模型】自动辅助驾驶的“大模型”时代

&#x1f388;边走、边悟&#x1f388;迟早会好 一、自动辅助驾驶实现与设计 1. 系统架构 1.1. 传感器系统 摄像头&#xff1a;提供前视、侧视、后视等多角度图像数据&#xff0c;用于检测车道线、交通标志、行人和其他车辆。雷达&#xff08;RADAR&#xff09;&#xff1a…

【python】PyQt5中QRadioButton的详细用法教程与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

论文速递 | Operations Research 6月文章合集

编者按&#xff1a; 在本系列文章中&#xff0c;我们梳理了运筹学顶刊Operations Research在2024年6月份发布的9篇相关文章的基本信息&#xff0c;旨在帮助读者快速洞察领域新动态。 推荐文章1 题目&#xff1a;Tight Guarantees for Multiunit Prophet Inequalities and On…

list模拟实现--用节点封装的迭代器问题

目录 一、list的使用 1.1list的构造 1.2list的iterator ​编辑 1.3 list的capacity 1.4 list的element access ​编辑 1.5list的mdifiers ​编辑 二、list的迭代器失效问题 三、list的模拟实现 3.1定义一个节点类 3.2用节点去封装迭代器 编译器对->的优化问题 …

JavaScript做网页是否过期的处理

通过路由上的参数生成唯一md5和路由上token做验证_md5 token-CSDN博客 前言&#xff1a;基于这篇文章我们做网页是否超时&#xff0c;网页是否过期的处理。打开一个网页允许他在一定时间内可以访问&#xff0c;过了这个时间就不可以访问了&#xff0c;encrypt是h5加密方法&…

数据仓库基础理论—维度建模(图文详解)

数据仓库基础理论—维度建模 维度建模是数据仓库设计中的一种核心方法&#xff0c;旨在以业务角度组织数据&#xff0c;使其更易于理解、查询和分析。 1. 维度模型的基本概念 1.1 事实表&#xff08;Fact Table&#xff09;&#xff1a; 事实表是维度模型的核心&#xff0…

ARM编程指令二

一、算术指令 1. add指令 功能: 将两个操作数相加&#xff0c;并将结果存储在目标寄存器中。 ADD R0, R1, R2 // R0 R1 R22. sub指令 功能: 将第二个操作数从第一个操作数中减去&#xff0c;并将结果存储在目标寄存器中。 SUB R0, R1, R2 // R0 R1 - R23.ADC指令- 带…

强化学习机械臂

一.前言 这里记录一下我学习强化学习的一些知识&#xff0c;并希望在今后可以通过仿真成功验证算法&#xff0c;如果时间允许的情况下希望可以结合到真实机械臂上。 二.学习过程 机械臂强化学习实战&#xff08;stable baselines3panda-gym&#xff09; 这里我先用anaconda创…