阿里P7大佬教你Kotlin 协程(2):协程启动篇

15、基于最优传输的协作多视图聚类框架 本文提出了一种基于最优传输理论的协作多视图聚类框架,通过引入协作学习机制在不同视图间建立先验交互,以提升共识聚类的质量。框架包含两种新方法:协作共识投影方法(CoCP)和基于新表示的协作共识方法(CoCNR)。CoCP在全局空间中整合多视图信息并进行共识投影,而CoCNR则通过协作编码生成新的数据表示以实现更优聚类。方法利用熵正则化的Wasserstein距离与Wasserstein重心,有效捕捉数据分布间的几何结构,并通过聚合步骤获得统一模型。实验结果表明,所提方法在多个数据集上均优于现有方法,具有良好的 阅读详情

解 Kotlin 协程(2) - 协程启动篇

现在你已经知道协程大概是怎么回事了,也应该想要自己尝试一把了吧。本文将为大家详细介绍协程的几种启动模式之间的不同,当然,我不打算现在就开始深入源码剖析原理,大家只需要记住这些规则就能很好的使用协程了。

1. 回想一下刚学 Thread 的时候

我相信现在接触 Kotlin 的开发者绝大多数都有 Java 基础,我们刚开始学习 Thread 的时候,一定都是这样干的:

val thread = object : Thread(){
    override fun run() {
        super.run()
        //do what you want to do.
    }
}
thread.start()

肯定有人忘了调用 start,还特别纳闷为啥我开的线程不启动呢。说实话,这个线程的 start 的设计其实是很奇怪的,不过我理解设计者们,毕竟当年还有 stop 可以用,结果他们很快发现设计 stop 就是一个错误,因为不安全而在 JDK 1.1 就废弃,称得上是最短命的 API 了吧。

既然 stop 是错误,那么总是让初学者丢掉的 start 是不是也是一个错误呢?

哈,有点儿跑题了。我们今天主要说 Kotlin。Kotlin 的设计者就很有想法,他们为线程提供了一个便捷的方法:

val myThread = thread {
    //do what you want
}

这个 thread 方法有个参数 start 默认为 true,换句话说,这样创造出来的线程默认就是启动的,除非你实在不想让它马上投入工作:

val myThread = thread(start = false) {
    //do what you want
}
//later on ...
myThread.start()

这样看上去自然多了。接口设计就应该让默认值满足 80% 的需求嘛。

2. 再来看看协程的启动

说了这么多线程,原因嘛,毕竟大家对它是最熟悉的。协程的 API 设计其实也与之一脉相承,我们来看一段最简单的启动协程的方式:

GlobalScope.launch {
    //do what you want
}

那么这段代码会怎么执行呢?我们说过,启动协程需要三样东西,分别是 上下文、启动模式、协程体,协程体 就好比 Thread.run 当中的代码,自不必说。

本文将为大家详细介绍 启动模式。在 Kotlin 协程当中,启动模式是一个枚举:

public enum class CoroutineStart {
    DEFAULT,
    LAZY,
    @ExperimentalCoroutinesApi
    ATOMIC,
    @ExperimentalCoroutinesApi
    UNDISPATCHED;
}

|
模式

|

功能

|
| — | — |
|

DEFAULT

|

立即执行协程体

|
|

ATOMIC

|

立即执行协程体,但在开始运行之前无法取消

|
|

UNDISPATCHED

|

立即在当前线程执行协程体,直到第一个 suspend 调用

|
|

LAZY

|

只有在需要的情况下运行

|

2.1 DEFAULT

四个启动模式当中我们最常用的其实是 DEFAULT 和 LAZY。

DEFAULT 是饿汉式启动, launch 调用后,会立即进入待调度状态,一旦调度器 OK 就可以开始执行。我们来看个简单的例子:

suspend fun main() {
    log(1)
    val job = GlobalScope.launch {
        log(2)
    }
    log(3)
    job.join()
    log(4)
}

说明: main 函数 支持 suspend 是从 Kotlin 1.3 开始的。另外,main 函数省略参数也是 Kotlin 1.3 的特性。后面的示例没有特别说明都是直接运行在 suspend main 函数当中。

这段程序采用默认的启动模式,由于我们也没有指定调度器,因此调度器也是默认的,在 JVM 上,默认调度器的实现与其他语言的实现类似,它在后台专门会有一些线程处理异步任务,所以上述程序的运行结果可能是:

19:51:08:160 [main] 1
19:51:08:603 [main] 3
19:51:08:606 [DefaultDispatcher-worker-1] 2
19:51:08:624 [main] 4

也可能是:

20:19:06:367 [main] 1
20:19:06:541 [DefaultDispatcher-worker-1] 2
20:19:06:550 [main] 3
20:19:06:551 [main] 4

这取决于 CPU 对于当前线程与后台线程的调度顺序,不过不要担心,很快你就会发现这个例子当中 2 和 3 的输出顺序其实并没有那么重要。

JVM 上默认调度器的实现也许你已经猜到,没错,就是开了一个线程池,但区区几个线程足以调度成千上万个协程,而且每一个协程都有自己的调用栈,这与纯粹的开线程池去执行异步任务有本质的区别。 当然,我们说 Kotlin 是一门跨平台的语言,因此上述代码还可以运行在 JavaScript 环境中,例如 Nodejs。在 Nodejs 中,Kotlin 协程的默认调度器则并没有实现线程的切换,输出结果也会略有不同,这样似乎更符合 JavaScript 的执行逻辑。 更多调度器的话题,我们后续还会进一步讨论。

2.2 LAZY

LAZY 是懒汉式启动, launch 后并不会有任何调度行为,协程体也自然不会进入执行状态,直到我们需要它执行的时候。这其实就有点儿费解了,什么叫我们需要它执行的时候呢?就是需要它的运行结果的时候, launch 调用后会返回一个 Job 实例,对于这种情况,我们可以:

  • 调用 Job.start,主动触发协程的调度执行
  • 调用 Job.join,隐式的触发协程的调度执行

所以这个所谓的”需要“,其实是一个很有趣的措辞,后面你还会看到我们也可以通过 await 来表达对 Deferred 的需要。这个行为与 Thread.join 不一样,后者如果没有启动的话,调用 join 不会有任何作用。

log(1)
val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
    log(2)
}
log(3)
job.start()
log(4)

基于此,对于上面的示例,输出的结果可能是:

14:56:28:374 [main] 1
14:56:28:493 [main] 3
14:56:28:511 [main] 4
14:56:28:516 [DefaultDispatcher-worker-1] 2

当然如果你运气够好,也可能出现 2 比 4 在前面的情况。而对于 join,

...
log(3)
job.join()
log(4)

因为要等待协程执行完毕,因此输出的结果一定是:

14:47:45:963 [main] 1
14:47:46:054 [main] 3
14:47:46:069 [DefaultDispatcher-worker-1] 2
14:47:46:090 [main] 4

2.3 ATOMIC

ATOMIC 只有涉及 cancel 的时候才有意义,cancel 本身也是一个值得详细讨论的话题,在这里我们就简单认为 cancel 后协程会被取消掉,也就是不再执行了。那么调用 cancel 的时机不同,结果也是有差异的,例如协程调度之前、开始调度但尚未执行、已经开始执行、执行完毕等等。

为了搞清楚它与 DEFAULT 的区别,我们来看一段例子:

log(1)
val job = GlobalScope.launch(start = CoroutineStart.ATOMIC) {
    log(2)
}
job.cancel()
log(3)

我们创建了协程后立即 cancel,但由于是 ATOMIC 模式,因此协程一定会被调度,因此 1、2、3 一定都会输出,只是 2 和 3 的顺序就难说了。

20:42:42:783 [main] 1
20:42:42:879 [main] 3
20:42:42:879 [DefaultDispatcher-worker-1] 2

对应的,如果是 DEFAULT 模式,在第一次调度该协程时如果 cancel 就已经调用,那么协程就会直接被 cancel 而不会有任何调用,当然也有可能协程开始时尚未被 cancel,那么它就可以正常启动了。所以前面的例子如果改用 DEFAULT 模式,那么 2 有可能会输出,也可能不会。

需要注意的是,cancel 调用一定会将该 job 的状态置为 cancelling,只不过 ATOMIC 模式的协程在启动时无视了这一状态。为了证明这一点,我们可以让例子稍微复杂一些:

log(1)
val job = GlobalScope.launch(start = CoroutineStart.ATOMIC) {
    log(2)
    delay(1000)
    log(3)
}
job.cancel()
log(4)
job.join()

我们在 2 和 3 之间加了一个 delay, delay 会使得协程体的执行被挂起,1000ms 之后再次调度后面的部分,因此 3 会在 2 执行之后 1000ms 时输出。对于 ATOMIC 模式,我们已经讨论过它一定会被启动,实际上在遇到第一个挂起点之前,它的执行是不会停止的,而 delay 是一个 suspend 函数,这时我们的协程迎来了自己的第一个挂起点,恰好 delay 是支持 cancel 的,因此后面的 3 将不会被打印。

我们使用线程的时候,想要让线程里面的任务停止执行也会面临类似的问题,但遗憾的是线程中看上去与 cancel 相近的 stop 接口已经被废弃,因为存在一些安全的问题。不过随着我们不断地深入探讨,你就会发现协程的 cancel 某种意义上更像线程的 interrupt。

2.4 UNDISPATCHED

有了前面的基础, UNDISPATCHED 就很容易理解了。协程在这种模式下会直接开始在当前线程下执行,直到第一个挂起点,这听起来有点儿像前面的 ATOMIC,不同之处在于 UNDISPATCHED 不经过任何调度器即开始执行协程体。当然遇到挂起点之后的执行就取决于挂起点本身的逻辑以及上下文当中的调度器了。

log(1)
val job = GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) {
    log(2)
    delay(100)
    log(3)
}
log(4)
job.join()
log(5)

我们还是以这样一个例子来认识下 UNDISPATCHED 模式,按照我们前面的讨论,协程启动后会立即在当前线程执行,因此 1、2 会连续在同一线程中执行, delay 是挂起点,因此 3 会等 100ms 后再次调度,这时候 4 执行, join 要求等待协程执行完,因此等 3 输出后再执行 5。以下是运行结果:

22:00:31:693 [main] 1
22:00:31:782 [main @coroutine#1] 2
22:00:31:800 [main] 4
22:00:31:914 [DefaultDispatcher-worker-1 @coroutine#1] 3
22:00:31:916 [DefaultDispatcher-worker-1 @coroutine#1] 5

方括号当中是线程名,我们发现协程执行时会修改线程名来让自己显得颇有存在感。运行结果看上去还有一个细节可能会让人困惑, join 之后的 5 的线程与 3 一样,这是为什么?我们在前面提到我们的示例都运行在 suspend main 函数当中,所以 suspend main 函数会帮我们直接启动一个协程,而我们示例的协程都是它的子协程,所以这里 5 的调度取决于这个最外层的协程的调度规则了。关于协程的调度,我们后面再聊。

3. 小结

本文通过一些例子来给大家逐步揭开协程的面纱。

更多的Kotlin 相关学习资料扫码免费领取!

《高级Kotlin强化实战 》

第一章 Kotlin 入门教程

​ ● Kotlin 概述

​ ● Kotlin 与 Java 比较

​ ● 巧用 Android Studio

​ ● 认识 Kotlin 基本类型

​ ● 走进 Kotlin 的数组

​ ● 走进 Kotlin 的集合

​ ● 完整代码

​ ● 基础语法

img

第二章 Kotlin 实战避坑指南

​ ● 方法入参是常量,不可修改

​ ● 不要 Companion、INSTANCE?

​ ● Java 重载,在 Kotlin 中怎么巧妙过渡一下?

​ ● Kotlin 中的判空姿势

​ ● Kotlin 复写 Java 父类中的方法

​ ● Kotlin “狠”起来,连TODO都不放过!

​ ● is、as` 中的坑

​ ● Kotlin 中的 Property 的理解

​ ● also 关键字

​ ● takeIf 关键字

​ ● 单例模式的写法

img

第三章 项目实战《Kotlin Jetpack 实战》

​ ● 从一个膜拜大神的 Demo 开始

​ ● Kotlin 写 Gradle 脚本是一种什么体验?

​ ● Kotlin 编程的三重境界

​ ● Kotlin 高阶函数

​ ● Kotlin 泛型

​ ● Kotlin 扩展

​ ● Kotlin 委托

​ ● 协程“不为人知”的调试技巧

​ ● 图解协程:suspend

img

《史上最详Android版kotlin协程入门进阶实战 》

Open3d Qt的环境配置 目前统一使用qt6配置,open3d中可视化功能目前使用vtk代替,语言为c++。 阅读详情

相关推荐

Zynq工程IP核封装:XCI引用与约束继承实战指南

IP核封装是FPGA系统设计中实现模块复用、团队协作与技术资产沉淀的关键环节。其本质是将功能逻辑、时序约束、接口协议和硬件配置统一抽象为可配置、可验证、可演进的标准化组件。核心原理在于通过XCI文件保留IP核的参数化定义能力,依托Vivado IP Packager实现约束继承、端口自动映射与时钟域解耦,从而保障跨项目集成的时序可信性与约束完备性。该技术广泛应用于Zynq SoC视频处理、高速接口(如HDMI/TMDS)、多时钟域控制系统等场景,尤其在需要长期维护与版本迭代的工业级嵌入式开发中具有不可替代的

weixin_42593701的博客 126

在Python里使用await关键字来等另外一个协程的实例!

一个协程里可以启动另外一个协程,并等待它完成返回结果,采用await关键字, 例子如下: import asyncio async def outer(): print('in outer') print('waiting for result1') result1 = await phase1() print('waiting for result2') result...

爬遍所有网站 214

World Creator地形导入UE

导出预设选择高度图(heigh map)格式选择PNG 16位,或者RAW 16位,需要反转y轴(与虚幻不同),命名格式会自动带一个× , 将×改成_ 或者删掉自己命名 (虚幻名称不支持x符号)导入虚幻 , 修改Z轴 , 就是用 地形最高 - 地形最低 , 然后除以512 , 再乘以100。把这个数字填入Z轴缩放 , 点击生成即可。

UE星空 2155

Kotlin 协程基础入门:协程的三种启动方式和挂起函数

通常,我们会在协程中使用挂起函数,并利用协程的上下文来管理执行环境。协程构建了一种轻量级的线程,将线程的状态保存在内存中,然后利用挂起函数实现了产生、挂起、恢复等机制,从而提供了非阻塞的多任务异步编程方式。withContext()是Kotlin协程库中的一个高级函数,它用于切换协程的执行上下文,例如在一个协程中切换到IO线程执行网络请求或者读写文件等操作。总之,挂起函数是 Kotlin 协程的重要概念,它本质是一种带有挂起(协程)能力的标记函数,它利用了协程和协程上下文机制来实现非阻塞式的异步编程。

WriteBug001的博客 1697

AI使用指南:6个超实用的Prompt提示词模板

最近越来越多人开始接触AI,但其实想要让AI更懂你,关键是掌握对的提示词模板!今天就给大家分享6种超实用的Prompt提示词模板,不管你是小白还是老手都能用

程序员世杰 8179

基于51单片机语音识别智能台灯设计

智能台灯;语音识别;STC89C52RC单片机

Benso_H的博客 5843

初次体验协程,对比线程有哪些优势(利用阿里库快速引入Quasar)

1. 什么是协程 简单可以理解为理解为用户态线程,在学过操作系统的时候我们知道,线程可以在用户态和内核态之间切换,目前java中所实现的线程都会有自己的上下文,上下文在线程的运行过程中会不断的切换,线程就会不断地从用户态和内核态之间切换。由此带来巨大开销。 协程:我们可以简单的理解为用户态线程,避免了内核态和用户态之间的切换来减少线程上下文切换的开销。 但是JVM原生是不支持这样的操作的。因此如果...

流的博客 1078

DeepSeek+Cline:开启自动化编程新纪元

随着 AI 技术不断进步,编程领域迎来效率变革。DeepSeek 与 Cline 的结合,成为自动化编程的强大工具。DeepSeek 凭借先进的自然语言处理能力,能精准理解编程需求;Cline 作为 VSCode 插件,可实现代码生成、调试、注释等功能的无缝衔接。本文详细阐述二者安装配置、实战操作流程,涵盖从基础代码生成到复杂项目开发的应用技巧,同时解答常见问题,帮助开发者快速掌握这对 “智能搭档”,提升编程效率,解锁自动化编程的无限可能。

邓邓子的博客 6256

阿里大牛整理的Python学习笔记:线程,进程,协程,建议收藏

一、线程(Thread)   1、定义:线程是操作系统能进行运算调度的最小单位,它包含在进程中,是进程的实际运作单位,一条线程是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。简单理解:线程是一系列指令的集合,操作系统通过这些指令调用硬件。   2、同一个线程中的所有线程共享同一个内存空间资源, 二、进程(Progress)   1、定义:一个程序对各资源管理和调用的集合就是进程,比如QQ对网卡、内存、硬盘的调度和管理。对于操作系统来说,某一个进程是统...

ITjianshuzhai的博客 636

SPMI总线协议(一)

系统电源管理接口( System Power Management Interface简称SPMI)是一种双线串行接口,用于连接片上系统(SoC)处理器系统的集成电源控制器(PC)与一个或多个电源管理集成电路(PMIC)电压调节系统。SPMI 使系统能够使用单个 SPMI 总线动态调整 SoC 内部电压域的电源和衬底偏置电压。移动设备和其他便携式设计正日益采用系SPMI)协议,实现多主多从系统,根据实时系统需求监测和动态控制供电电压。设计人员可以在系统级实现更低的功率。

qflook的博客 888

【实验】ENSP 实战:酒店有线 + 无线三层组网全配置(VLAN 规划 + AC/AP+SSID 绑定)

三层架构:出口路由器 → 核心交换机 → 汇聚交换机 → 接入交换机 / AP / 终端。

jundao1997的专栏 431

阿里开源 iOS 协程开发框架 coobjc 简易学习

如果现在感到压力很大,可能现在的目标与当前你的总体状态(身体状态,心理状态,外围环境,目标强度)不好,需要切换一个切实可行的目标。压力不要太大。 https://mp.weixin.qq.com/s/hXmkd0TqTrCD-4kYlZcqvQ 1、协程也是一种程序组件,协程与子例程一样。 2、一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多...

探究苹果技术原理和学习新技术(锲而舍之,朽木不折;锲而不舍,金石可镂。) 1535

基于LLM【M3】驱动的自动化攻击智能体AK(受控使用)

摘要:文章实测了基于大模型的目标驱动型云攻击智能体,展示攻击者仅需输入业务目标(如"窃取BigQuery数据")即可自动完成SSRF、令牌解析、数据导出等全链条攻击。研究发现:(1)攻击编排范式已从固定脚本升级为自适应路径;(2)传统基于IOC的防御与新型攻击存在结构性错位;(3)防御需转向元数据加固、跨服务行为序列检测和AI驱动的紫队演练。实验在授权靶场使用合成数据,验证了攻击智能体"监督者模型+专业执行组"的协作模式,强调防御体系需从单点检测升级为攻击链理解能力。

云上笛暮 307

阿里P7大佬教你破解 Kotlin 协程(3) - 协程调度篇

有了前面的基础,我们对于调度器的介绍就变得水到渠成了。......它本身是协程上下文的子类,同时实现了拦截器的接口,dispatch方法会在拦截器的方法中调用,进而实现协程的调度。所以如果我们想要实现自己的调度器,继承这个类就可以了,不过通常我们都用现成的,它们定义在这个类的定义涉及到了 Kotlin MPP 的支持,因此你在 Jvm 版本当中还会看到,在 js 和 native 当中就只有前面提到的这三个了(对 Jvm 好偏心呐)。JvmJsNativeDefault线程池。

Android_XG的博客 371

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

阿里P7大佬教你破解 Kotlin 协程(6) - 协程挂起篇

​ ● 协程是什么​ ● 什么是Job 、Deferred 、协程作用域​ ● Kotlin协程的基础用法。

Android_XG的博客 268

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

阿里P7大佬教你破解 Kotlin 协程(5) - 协程取消篇

​ ● 协程是什么​ ● 什么是Job 、Deferred 、协程作用域​ ● Kotlin协程的基础用法。

Android_XG的博客 535

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

阿里P7大佬教你Kotlin协程实现原理:挂起与恢复

P7大佬教你Kotlin协程实现原理:挂起与恢复

Android_XG的博客 703

阿里P7大佬教你破解 Kotlin 协程(4) - 异常处理篇

​ ● 协程是什么​ ● 什么是Job 、Deferred 、协程作用域​ ● Kotlin协程的基础用法[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直

Android_XG的博客 491

kotlin 协程基础,阿里p8 hr面试

CoroutineContext是一系列元素的集合,主要的元素是代表协程的Job,此外还有协程的dispatcher等(Job、Dispatchers与CoroutineName都实现了Element接口)。CoroutineScope封装了CoroutineContext:针对于上面的问题,我总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料。

2301_79098332的博客 902

阿里P7大佬教你破解 Kotlin 协程(7) - 序列生成器篇

​ ● 协程是什么​ ● 什么是Job 、Deferred 、协程作用域​ ● Kotlin协程的基础用法。

Android_XG的博客 211

阿里P7大佬教你 Kotlin 协程(1) - 入门篇

Kotlin 协程(1) - 入门篇

Android_XG的博客 354

P7阿里大佬教你破解 Kotlin 协程(10) - Select 篇

在协程当中,Select 的语义与 Java NIO 或者 Unix 的 IO 多路复用类似,它的存在使得我们可以轻松实现 1 拖 N,实现哪个先来就处理哪个。尽管 Select 和 Channel 比起标准库的协程 API 已经更接近业务开发了,不过个人认为它们仍属于相对底层的 API 封装,在实践当中多数情况下也可以使用 Flow API 来解决。而这个 Flow API,完全就是响应式编程的协程版 API,我们简直可以照着 RxJava 来学习它,所以我们下一篇再见吧~~~,这样反而将问题复杂化了。

Android_XG的博客 183

阿里P8大佬带你真正理解一波Kotlin协程

1概述 目录 前言 Kotlin协程,现在已经成为了面试甚至是工作中一个非常火的东西。 本人在刚开始了解Kotlin协程的时候,断断续续看了网上不少文章,用长篇大论把Kotlin协程描述的非常玄乎,但是看完后还是依然云里雾里,所以决定来写一篇关于协程的文章,希望能够帮助大家能够更快的上手Kotlin协程. 注意:如果没有特殊提及,文中所有“协程”均代表“Kotlin协程” 2为什么要学习Kotlin协程?(官方版) 现在Android技术栈上的新东西层出不穷,kotlin、jetpa.

CHAMPION8888的博客 561

2024年Android最全万字长文 - Kotlin 协程进阶,2024年最新字节跳动面试笔试

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。还有高级架构技术进阶脑图、高级进阶架构资料帮助大家学习提升进阶,也可以分享给身边好友一起学习。一起互勉~网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取一个人可以走的很快,但一群人才能走的更远!

2401_84562143的博客 815

【kotlin 协程】万字协程 一篇完成kotlin 协程进阶_kotlin

但是他们再有子协程的话,他们的子协程的父级就不是SupervisorJob了,所以当它们产生异常时,就不是我们演示的效果了。,但是他们再有子协程的话,他们的子协程的父级就不是SupervisorJob了,所以当它们产生异常时,就不是我们演示的效果了。这种情况有的时候并不是我们想要的,我们更希望一个协程在产生异常时,不影响其他协程的执行,在上文中我们也提到了一些解决方案,下面我们就在实践一下。函数的创建者对函数的使用者的提醒:我是一个耗时函数,我被我的创建者用挂起的方式放在后台运行,所以请在协程里调用我。

2401_84184638的博客 895

Kotlin(九,阿里P7大牛亲自教你

| join() | 等待协程执行完毕 | | cancel() | 取消一个协程 | 协程的启动 public fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job{ val new

m0_61418455的博客 220
上一篇: 寒冬之际,6年Android开发转入车载方向
下一篇: 针对当下的行情,普通程序员要怎样规划职业生涯?
不秃头de程序猿
博客等级 码龄5年 4089粉丝 1478原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值