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

【Coroutines】Full Understanding of Kotlinx.Corutines Framework

文章目录

          • What is Corutines
          • Difference between Corutine and Thread
          • Fast Usage
          • Suspend Function
          • Advanced Usage of Coroutine
          • Coroutine Essentials
          • CoroutineContext
          • CoroutineScope
          • Predefined CoroutineScope
          • Predefined Dispatchers
          • Predefined CoroutineStart
          • Job
          • Create a Coroutine
          • ContinuationInterceptor
          • CoroutineExceptionHandler

What is Corutines

corutines is a modern way of async programming

a corutine is a async code block that supports suspend and resume

typically the code block looks like a synchronous block, but actually executed in async way

Difference between Corutine and Thread

both corutine and thread can achieve async works

for this point, they are the same, corutine can be regard as light-weight thread

but in fact, corutine is more a programming pattern, it cares how to write code easily

while thread is a hardware concept, it cares how cpu really works in concurrent situation

multiple corutines can run on same thread, also can run on different threads

corutines emphase how to write async code, while threads emphase the actual performance

corutines depend on threads, but it simplify traditional async programming with thread apis

Fast Usage

launch start a corutine to handle async work

step 2 will output before step 1 , because coroutine will not block code in host

import kotlinx.coroutines.*suspend fun main() {GlobalScope.launch {delay(1000L)println("step 1")}println("step 2")delay(999*1000L)
}

async start a corutine that have a return value

the return value which called deferred , can be used in other corutine

step 1 will output before step 2 this time, as corutine 2 will wait result of corutine 1

step 3 will still output before step 1

import kotlinx.coroutines.*suspend fun main() {val deferred = GlobalScope.async {delay(5000L)println("step 1")return@async 100}GlobalScope.launch {println("step 2 ${deferred.await()}")}println("step 3")delay(99000L)
}
Suspend Function

from demos above, we can see a keyword called suspend

suspend means that this function can hang up, and continue handling work in another place

suspend function can only be called from coroutine block, or other suspend functions

because only coroutine has the ability to suspend and resume, normal functions was not able to do this

behavior contrary to suspend is resume , which is often hidden under the mask of coroutines framework

Advanced Usage of Coroutine

there are many variant forms to use coroutines

you can launch a coroutine using kotlinx.coroutines library like this

import kotlinx.coroutines.*suspend fun main() {val parentJob = Job()val scope = CoroutineScope(parentJob)val dispatcher = Dispatchers.Defaultval start = CoroutineStart.LAZYval job = scope.launch(dispatcher, start) {println("coroutine by launch")}job.start()delay(999*1000L)
}
Coroutine Essentials

a coroutine contains may composed of many essentials

now, let’s introduce them one by one, please take patience here

  • CoroutineContext : all essentials that determine how coroutine works
  • CoroutineScope : offer a scope of current coroutine, determine which coroutine you are writting in
  • CoroutineDispatcher : decide which thread coroutine work on
  • CoroutineStart : decide when to execute coroutine block
  • CoroutineExceptionHandler : how to handle exception when error occurs
  • ContinuationInterceptor : intercept current coroutine, and create a new coroutine based on current
  • most common implementation of ContinuationInterceptor is CoroutineDispatcher
  • Job : present the task that coroutine handles, can be cancelled manually
  • CoroutineName : give a name for current coroutine
CoroutineContext

CoroutineContext is the base class of most coroutine essential instances

coroutine context can be a single essential, or a collection of multiple essentials

context can be a standalone essential, also can hold some child essentials

likes a data struct below

class Context : Map<Key, Context>

a coroutine context can be added to another context, then form a new context contains both of them

if key is not contained in current context, add it, otherwise, replace it

val newCoroutineContext = currentContext + contextItem

coroutine essentials can be obtained from context through specific key

val job = context[Job]
val name = context[CoroutineName]
val dispather = context[CoroutineDispatcher]
val interceptor = context[ContinuationInterceptor]
val errorHandler = context[CoroutineExceptionHandler]

CoroutineContext has a direct child interface called CoroutineContext.Element

most classes are directly inherited from Element but not Context

they are actually the same thing

but Element emphas the class is intented to resolve specific requirement, not act as a collection

CoroutineScope

coroutine scope hold a coroutine context object named coroutineContext

coroutineContext holds all essentials for current coroutine

design intents of CoroutineScope can cover two aspects

  • hide internal functions of actual CoroutineImpl
  • offer a block scope object to control current coroutine

coroutine scope can be cancelled, when scope is cancelled, coroutine is cancelled

in fact, coroutine scope cancell coroutine by delegate object obtained from coroutineContext[Job]

Predefined CoroutineScope
  • GlobalScope

    an empty scope, cannot be cancelled, always available

  • LifecycleScope

    bind with android LifecycleOwner, when lifecycle is destroyed, scope will be cancelled

  • ViewModelScope

    bind with android ViewModel, when ViewModel is cancelled, scope will be cancelled

Predefined Dispatchers
  • Dispatchers.Default

    post to default thread pool, designed to handle computation work

  • Dispatchers.IO

    post to default thread pool, designed to handle computation work

  • Dispatchers.Main

    post to ui thread, designed to handle ui work, implementation depend on platform adapter

  • Dispatchers.Unconfined

    not change thread, execute immediately

there are some details we should concern

  • Dispatchers.Default and Dispatchers.IO share the same thread pool

    but each thread has a flag, to indicate whether receive cpu-intensive-work or memory-intensive-work

  • when Dispatchers.Unconfined is continuously used in child coroutines

    tasks will be post to event loop queue, maintained in current thread, to avoid StackOverflow error

Predefined CoroutineStart

CoroutineStart define the start strategy of coroutines

before introduce of those strategies, let’s understand differences between dispatch and execute first

execute means coroutine block is executed

dispatch means coroutine block is post to thread or task queue, but not executed yet

execute always happens behind dispatch

  • CoroutineStart.DEFAULT

    dispatched immediately, can be cancelled before dispatch

  • CoroutineStart.ATOMIC

    dispatched immediately, but cannot be cancelled until block suspended

  • CoroutineStart.LAZY

    not dispatched, until start api is actively called, such as start join await

  • CoroutineStart.UNDISPATCHED

    executed immediately in current calling-stack, not dispatched, until block’s first suspend

CoroutineStart.DEFAULT and CoroutineStart.LAZY are the most common ways

while CoroutineStart.ATOMIC and CoroutineStart.UNDISPATCHED are design for special scenarios

Job

represent the task coroutine handles, returned when coroutine is created

can be used to start or cancel a coroutine, and query coroutine state

  • start : start coroutine
  • cancel : cancel coroutine
  • join : join another coroutine and wait completed
  • parent : get parent job
  • isCancelled : query whether coroutine is cancelled
  • isCompleted : query whether coroutine is completed
  • invokeOnCompletion : set cancel or complete callback
Create a Coroutine

kotlinx.coroutines framework offers several ways to create coroutines

  • CoroutineScope.launch

    create a coroutine, without blocking current calling stack

  • CoroutineScope.async

    create a coroutine, with a FutureResult called Deferred returned, not blocking current calling stack

    value in Deferred can be got by await, blocking current calling stack until value returned

  • withContext(CoroutineContext, CoroutineScope.() -> R)

    create a coroutine, with specified context, blocking current calling stack until block finished and value returned

  • CoroutineDispatcher.invoke(CoroutineScope.() -> R)

    create a coroutine, with specified dispatcher, blocking current calling stack until block finished and value returned

    in fact, this is a inline function, actually calls withContext(dispatcher, block)

  • runBlocking(CoroutineContext, CoroutineScope.() -> T)

    create a coroutine, with specified context, blocking until block finished and value returned

    this function will not only block calling stack, but also block current thread

    it is designed to use suspend-style apis in non-suspend functions

    only suggest using it in main function or unit test functions

  • coroutineScope(CoroutineScope.() -> R)

    create a coroutine based on current coroutine context, equivalent to withContext(coroutineContext, block)

  • supervisorScope(CoroutineScope.() -> R)

    like coroutineScope, but child coroutine’s exception won’t be delivered to parent coroutine

all coroutines will start automatically by default, unless you specify other start strategy

ContinuationInterceptor

interceptor can intercept current coroutine, and extend extra operations based on origin coroutine

taking Dispatcher as an example, it handles the same work as the origin coroutine, with a thread switch operation extended

CoroutineExceptionHandler

there are two chances can trigger exception

  • error occurs, and exception is thrown
  • error saved in result, and get result is called

there are several handlers can handle exception

  • exception handler from parent coroutine
  • exception handler from current coroutine
  • exception handler from thread

how exception deliver between coroutine depends on many factors

it is a complex subject, we will talk about it in next blog

相关文章:

【Coroutines】Full Understanding of Kotlinx.Corutines Framework

文章目录 What is CorutinesDifference between Corutine and ThreadFast UsageSuspend FunctionAdvanced Usage of CoroutineCoroutine EssentialsCoroutineContextCoroutineScopePredefined CoroutineScopePredefined DispatchersPredefined CoroutineStartJobCreate a Corou…...

Python面向对象,实现图片处理案例,支持:高斯模糊、Canny边缘检测、反转边缘图像、生成手绘效果、调亮度......等等

实验图片如下&#xff1a; 命名为img1.jpg, 放在项目下新建文件夹images下 项目构造如下&#xff1a; app.py源码如下 import cv2 import os from matplotlib import pyplot as plt import numpy as npclass ImageProcessor:def __init__(self, image_path):self.image cv…...

SOLID - 依赖倒置原则(Dependency Inversion Principle)

SOLID - 依赖倒置原则&#xff08;Dependency Inversion Principle&#xff09; 定义 依赖倒置原则&#xff08;Dependency Inversion Principle&#xff0c;DIP&#xff09;是面向对象设计中的五大基本原则之一&#xff0c;通常缩写为SOLID中的D。DIP由Robert C. Martin提出&…...

【.NET 8 实战--孢子记账--从单体到微服务】--需求拆分与规划

在上一篇文章中我们收集了需求&#xff0c;并对需求进行了简单的分析和规划&#xff0c;但是对于开发人员来说&#xff0c;上一篇文章的需求还不够详细&#xff0c;并且没有形成计划。因此本篇文章将带领大家来拆分需求并规划开发里程碑。 一、详细需求列表 项目组进行了多次…...

在macOS的多任务处理环境中,如何平衡应用的性能与用户体验?这是否是一个复杂的优化问题?如何优化用户体验|多任务处理|用户体验|应用设计

目录 一 多任务处理与应用性能 1. macOS中的多任务处理机制 2. 性能优化的基本策略 二 用户体验的关键要素 1. 响应速度 2. 界面友好性 3. 功能的直观性 三 平衡性能与用户体验的策略 1. 资源管理 2. 优化数据加载 3. 使用合适的线程模型 4. 实时监测和调整 四 使…...

Vscode配置CC++编程环境的使用体验优化和补充说明

文章目录 快速编译运行&#x1f47a;code runner插件方案Code Runner Configuration 直接配置 相关指令和快捷键默认task配置和取消默认 配置文件补充介绍(可选 推荐阅读)&#x1f60a;使用vscode预置变量和环境变量环境变量的使用使用环境变量的好处环境变量可能引起的问题 检…...

十个方法杜绝CAD图纸泄密风险!2024年图纸防泄密指南!「必看」

随着信息技术的发展&#xff0c;CAD图纸的应用日益普遍&#xff0c;然而随之而来的图纸泄密风险也愈加严重。企业在提升效率的同时&#xff0c;更需重视信息安全。为此&#xff0c;本文将介绍十个有效的方法&#xff0c;帮助企业杜绝CAD图纸泄密风险&#xff0c;保障商业机密。…...

技术干货|HyperMesh CFD功能详解:虚拟风洞 Part 1

虚拟风洞VWT 从2023版本开始&#xff0c;虚拟风洞VWT&#xff08;Virtual Wind Tunnel&#xff09;模块合并到HyperMesh CFD中。 用户在VWT模块中完成LBM求解器ultraFluidX的前处理设置&#xff0c;导出参数文件XML和模型文件STL&#xff0c;并在GPU服务器上提交计算。 VWT目前…...

022集——统计多条线的总长度(CAD—C#二次开发入门)

如下图所示&#xff0c;选择多条线并统计长度&#xff1a; c#中不包含直接获取curve曲线长度 属性&#xff0c;需用如下方法&#xff1a;curve.GetDistanceAtParameter(item.EndParam) 附部分代码如下&#xff1a; using Autodesk.AutoCAD.ApplicationServices; using Autode…...

大模型重要技术系列三:高效推理

接上一篇高效训练&#xff0c;这一篇汇总下高效推理的方法。高效推理的两个主要优化目标是低延迟&#xff08;快速得到推理结果&#xff09;和高吞吐量&#xff08;能同时处理很多请求&#xff09;&#xff0c;同时还要尽可能地少用资源&#xff08;算力、存储、网络带宽&#…...

Android 刘海屏适配指南

如果您不希望您的内容与刘海区域重叠&#xff0c; 以确保您的内容不会与状态栏及 导航栏。如果您要呈现在刘海区域中&#xff0c;请使用 WindowInsetsCompat.getDisplayCutout() 检索 DisplayCutout 对象 包含每个刘海屏的安全边衬区和边界框。借助这些 API 您需要检查视频内容…...

微信小程序服务通知

项目中用到了小程序的服务消息通知&#xff0c;通知订单状态信息&#xff0c;下边就是整理的一下代码&#xff0c;放到项目中&#xff0c;把项目的小程序appid和小程序的secret写进去&#xff0c;直接运行即可 提前申请好小程序服务信息通知短信模板&#xff0c;代码需要用到模…...

Ubuntu使用Qt虚拟键盘,支持中英文切换

前言 ​ 最近领导给了个需求&#xff0c;希望将web嵌入到客户端里面&#xff0c;做一个客户端外壳&#xff0c;可以控制程序的启动、停止、重启&#xff0c;并且可以调出键盘在触摸屏上使用(我们的程序虽然是BS架构&#xff0c;但程序还是运行在本地工控机上的)&#xff0c;我…...

泰州农商行

该文章用于测试&#xff0c;暴露面检测服务 1595116111115951161112159511611131595116111415951161115159511611161595116111715951161118159511611191595116112015951161121159511611221595116112315951161124159511611251595116112615951161127159511611281595116112915951…...

扫雷(C语言)

目录​​​​​​​ 前言 一、前提知识 二、扫雷游戏编写 2.2 test文件基本逻辑 2.2.1菜单编写 2.2.2game函数的逻辑 2.2.2.1定义两个数组 2.2.2.2两个数组数组的初始化 2.2.2.3打印棋盘 2.2.2.4布置雷 2.2.2.5排查雷 2.2.2.6获取坐标附近雷的数量 2.2.2.7什么时候…...

【实践功能记录8】使用UseElementSize实现表格高度自适应

一、关于 UseElementSize UseElementSize 是一个 Vue 组合式 API 的实用工具&#xff0c;通常用于获取 DOM 元素的尺寸信息&#xff0c;例如宽度、高度等。它通常与 v-slot 一起使用&#xff0c;以便在模板中直接访问这些尺寸信息。 地址&#xff1a;https://vueuse.org/core/u…...

SMO算法 公式推导

min ⁡ α 1 2 ∑ i 1 N ∑ j 1 N α i α j y i y j K ( x i ⋅ x j ) − ∑ i 1 N α i s.t. ∑ i 1 N α i y i 0 0 ≤ α i ≤ C , i 1 , 2 , ⋯ , N (9-69) \begin{aligned} & \min_{\alpha} \quad \frac{1}{2} \sum_{i1}^{N} \sum_{j1}^{N} \alpha_i \alpha_j…...

nodejs包管理器pnpm

简介 通常在nodejs项目中我们使用npm或者yarn做为默认的包管理器&#xff0c;但是pnpm的出现让我们的包管理器有了更多的选择&#xff0c;pnpm相比npm具有以下优势&#xff1a; 速度更快&#xff0c;pnpm在安装依赖时&#xff0c;会将依赖包缓存到全局目录&#xff0c;下次安…...

【postman】工具下载安装

postman作用 postman用于测试http协议接口&#xff0c;无论是开发, 还是测试人员, 都有必要学习使用postman来测试接口, 用起来非常方便。 环境安装 postman 可以直接在chrome 上安装插件&#xff0c;当然大部分的同学是没法连接到谷歌商店的&#xff0c;我们可以在电脑本地…...

Java_Springboot核心配置详解

Spring Boot以其简洁、高效和约定优于配置的理念&#xff0c;极大地简化了Java应用的开发流程。在Spring Boot中&#xff0c;核心配置是应用启动和运行的基础。本文将详细介绍Spring Boot中的两种配置文件格式、基础注解的配置方式、自定义配置以及多环境配置。 一、Spring Bo…...

太速科技-9-基于DSP TMS320C6678+FPGA XC7V690T的6U VPX信号处理卡

基于DSP TMS320C6678FPGA XC7V690T的6U VPX信号处理卡 一、概述 本板卡基于标准6U VPX 架构&#xff0c;为通用高性能信号处理平台&#xff0c;系我公司自主研发。板卡采用一片TI DSP TMS320C6678和一片Xilinx公司Virtex 7系列的FPGA XC7V690T-2FFG1761I作为主处理器&#…...

在线UI设计工具:创意与效率的结合

随着UI设计领域的快速增长&#xff0c;设计师们纷纷投身于这一行业&#xff0c;选择一款合适的UI设计工具变得至关重要。除了经典的UI设计软件&#xff0c;在线UI设计工具因其灵活性和便捷性&#xff0c;越来越受到设计师们的喜爱。这种不受时间和地点限制&#xff0c;且不依赖…...

【MyBatis源码】SqlSessionFactoryBuilder源码分析

文章目录 概述类结构从 InputStream 创建 SqlSessionFactoryXMLConfigBuilder构建ConfigurationXMLConfigBuilder初始化方法parse()方法parseConfiguration属性&#xff08;properties&#xff09; 概述 SqlSessionFactory 是 MyBatis 的核心接口之一&#xff0c;提供创建 Sql…...

Percona XtraBackup数据备份方案

一、简介 官方文档:https://docs.percona.com/percona-xtrabackup/innovation-release/index.html Percona XtraBackup 是一款适用于基于 MySQL 的服务器的开源热备份实用程序,可让您的数据库在计划的维护时段内保持完全可用。无论是 24x7 高负载服务器还是低交易量服务器,…...

聚“芯”而行,华普微亮相第五届Silicon Labs Works With大会

2024年10月24日&#xff0c;由致力于以安全、智能无线连接技术建立更互联世界的全球领导厂商Silicon Labs主办的第五届Works With开发者大会在上海雅乐居万豪侯爵酒店成功举办。 作为全球性的物联网年度“盛宴”&#xff0c;本届大会群英荟萃&#xff0c;不仅有着来自生态大厂的…...

Java 用户随机选择导入ZIP文件,解压内部word模板并入库,Windows/可视化Linux系统某麒麟国防系统...均可适配

1.效果 压缩包内部文件 2.依赖 <!--支持Zip--><dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>2.11.5</version></dependency>总之是要File类变MultipartFile类型的 好像是…...

【C++】C++17结构化绑定、std::optional、std::variant、std::any

二十二、C17中的结构化绑定、std::optional、std::variant、std::any 本部分是一个小系列&#xff0c;介绍C17中新引入的、用来解决各种不同返回情况的、标准库新组件。 1、C的结构化绑定 结构化绑定structured bindings是C17中引入的一项特性&#xff0c;它允许开发者方便地…...

C#的起源。J++语言的由来?J#和J++傻傻分不清?

C#的起源 C#读音是C Sharp, 它是微软为了对抗Java而生&#xff0c;最早是J&#xff0c;效率比Java还好&#xff0c;后来被Sun公司起诉J破坏了平台无关性&#xff0c;微软重新开发C#. C#和Java一样都定位为中间件语言&#xff0c;用虚拟机执行编译的字节码以达到跨平台目的。从语…...

Flutter 在 对接 google play 时,利用 android studio 可视化生成 已签名的aab包

android studio 可视化生成 aab包 第一 &#xff1a; 先说注意事项 在Flutter项目里面&#xff0c;直接打开当前项目是不行的&#xff0c;不显示相应操作&#xff0c;需要在Android 目录打开&#xff0c;直白点就是直接打开项目里面的Android 目录 不然会出现的一些问题 第一…...

使用web.dev提供的工具实现浏览器消息推送服务

文章目录 前言实现工具和效果实现原理实现过程前端接收用户订阅请求将用户订阅信息更新到后端后端实现接收并保存订阅信息的接口后端实现消息推送的逻辑前言 对于电商独立站来说,新品上架或者促销活动上线及时通知到用户是很重要的,通知的渠道有很多,其中就包括浏览器消息推…...