kotlin-协程(什么是一个协程)

1.什么指一个协程对于线程来说一个thread就是就是指一个线程,thread为什么成为线程呢?因为他实现了对线程的一个抽象管理,可以管理这个线程,启动,可以查看各种信息

那么协程呢?

public fun CoroutineScope.launch(context: CoroutineContext = EmptyCoroutineContext,start: CoroutineStart = CoroutineStart.DEFAULT,block: suspend CoroutineScope.() -> Unit
): Job {val newContext = newCoroutineContext(context)val coroutine = if (start.isLazy)LazyStandaloneCoroutine(newContext, block) elseStandaloneCoroutine(newContext, active = true)coroutine.start(start, coroutine, block)return coroutine
}可以看到,启动协程的时候创建了一个StandaloneCoroutine的对象,这个对象是Job的实现类,返回了一个job对象。

job有什么方法呢?

job.start()  //启动协程, start: CoroutineStart = CoroutineStart.LAZY
// ,的时候得使用job.start方法才会启动协程,才会调用block的代码
job.cancel() //取效协程
job.isActive  //判读协程的状态
job.join()   //当前的协程阻塞,等待job的协程结束后,再执行当前协程的代码
job.children //子协程的job对象
job.parent //父协程的job对象
job.cancelChildren() //取消所有子协程

那是不是意味着可以把job对象看作一个协程对象呢? 可以也行,但不是全部,job只是管理了协程流程相关的功能,比如开启结束等,但是像协程的名字等是没有的

CoroutineScope是信息最多的,包含可以获取协程的调度器,job等,以及调用launch 和 async去启动一个新的协程,而StandaloneCoroutine也是继承CoroutineScope的

而CoroutineScope里面有一个属性是CoroutineScope,里面全是协程的配置信息

比如:调度器,协程名称,启动模式等

public interface CoroutineScope {public val coroutineContext: CoroutineContext
}

协程的父子协程

val parentJob = launch {childJob =  launch {delay(200)}}

协程的父子协程是根据job来决定的,在上面的代码中,会把parentJob赋值给childJob的parent属性,会把childJob赋值给parentJob的childJob属性。那怎么相互拿到对方的job呢?

在父协程中启动launch的时候,因为本身就是通过 。CoroutineScope启动的,而CoroutineScope的 coroutineContext 中就可以拿到这个Job。

  runBlocking {var childJob:Job?= nullval parentJob = launch(Dispatchers.IO) {childJob =  launch {delay(200)}}println("parentJOb${parentJob }")println("childJob=${childJob }")println("childJOb = parentJOb=${childJob?.parent == parentJob }")}

其实看源码可以看到他是复制了父类的coroutineContext的内容

public fun CoroutineScope.launch(context: CoroutineContext = EmptyCoroutineContext,start: CoroutineStart = CoroutineStart.DEFAULT,block: suspend CoroutineScope.() -> Unit
): Job {val newContext = newCoroutineContext(context)val coroutine = if (start.isLazy)LazyStandaloneCoroutine(newContext, block) elseStandaloneCoroutine(newContext, active = true)coroutine.start(start, coroutine, block)return coroutine
}
我们看newCoroutineContextnewCoroutineContext是CoroutineScope的扩展函数,
所以可以拿到当前调用他的launch的CoroutineScope的coroutineContext,和传入的context共同创建一个新的contextpublic actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {val combined = foldCopies(coroutineContext, context, true)val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combinedreturn if (combined !== Dispatchers.Default && combined[ContinuationInterceptor] == null)debug + Dispatchers.Default else debug
}

 

kotlin 

这里说下我的疑惑点:

第一:parentJob是在  println之前赋值的吗? 

打印结果:

parentJObStandaloneCoroutine{Active}@4b553d26
childJob=StandaloneCoroutine{Active}@69a3d1d
childJOb = parentJOb=true

val parentJob = launch(Dispatchers.IO) {childJob =  launch {delay(200)}}

这个代码,虽然指定了Dispatchers.IO,但是只是说把block函数扔进了子线程,但是赋值给parentJob是在主线程的,所以在println之前,但是childJob不一定了

public fun CoroutineScope.launch(context: CoroutineContext = EmptyCoroutineContext,start: CoroutineStart = CoroutineStart.DEFAULT,block: suspend CoroutineScope.() -> Unit
): Job {val newContext = newCoroutineContext(context)val coroutine = if (start.isLazy)LazyStandaloneCoroutine(newContext, block) elseStandaloneCoroutine(newContext, active = true)coroutine.start(start, coroutine, block)return coroutine    //立即返回对象
}

kotlin的父子协程关系就是通过job来绑定的。

假如,我们把childJob的launch传一个job进去,他们就不是父子协程了,这个时候childJob的父协程是传进去的job,注意传进去的job是父job.

fun main() {runBlocking {CoroutineScope(EmptyCoroutineContext)var childJob:Job?= nullval parentJob = launch(Dispatchers.Default) {childJob =  launch(Job()) {delay(200)}delay(300)}println("parentJOb${parentJob }")println("childJob=${childJob }")println("childJOb = parentJOb=${childJob?.parent == parentJob }")}
}

下面的代码打印结果是什么 

   fun main() {runBlocking {var job1: Job? =nullvar coroutineScope:CoroutineScope? = nullval  job =  launch {job1= this.coroutineContext[Job]coroutineScope = thisdelay(3000)}delay(100)println("coroutineScope === job1=${coroutineScope === job1 }")println("job === job1=${job === job1 }")}
}

coroutineScope === job1=true
job === job1=true

意思是他们三个其实是一个对象

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

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

相关文章

七、深入 Hive DDL:管理表、分区与洞察元数据

作者:IvanCodes 日期:2025年5月13日 专栏:Hive教程 内容导航 一、表的 DDL 操作 (非创建)二、分区的 DDL 操作三、洞察元数据:SHOW 命令的威力结语:DDL 与 SHOW,Hive 管理的双翼练习题一、选择题二、代码题…

【 Redis | 实战篇 短信登录 】

前言: 主要完成了基于Session实现登录,解决集群的Session共享问题,从而实现了基于Redis来实现共享Session登录 1.基于Session实现登录 1.1.发送短信验证码 步骤: 前端提交手机号 》校验手机号 》不符合返回错误信息&#xff0…

蓝桥杯14届国赛 合并数列

问题描述 小明发现有很多方案可以把一个很大的正整数拆成若干正整数的和。他采取了其中两种方案,分别将他们列为两个数组 {a1,a2,...,an} 和 {b1,b2,...,bm}。两个数组的和相同。 定义一次合并操作可以将某数组内相邻的两个数合并为一个新数,新数的值是…

Doris和Clickhouse对比

目录 一、Doris和Clickhouse对比1. 底层架构**DorisClickHouse** 2. 运行原理DorisClickHouse 3. 使用场景DorisClickHouse 4. 优缺点对比总结 二、MPP架构和Shared-Nothing 架构对比1. 什么是 MPP 架构?定义特点典型代表 2. 什么是 Shared-Nothing 架构&#xff1f…

niushop单商户V5多门店版V5.5.0全插件+商品称重、商家手机端+搭建环境教程

一.系统介绍 【全开源】niushop单商户V5多门店版V5.5.0版本,我看很多人都想要 商品称重、商家手机端等插件这套是全插件版本,整合起来本博主也花了不少啦~ Niushop系统是应用thinkphp6开发的完善的电商系统,拥有完善的商品机制,…

内存、磁盘、CPU区别,Hadoop/Spark与哪个联系密切

1. 内存、磁盘、CPU的区别和作用 1.1 内存(Memory) 作用: 内存是计算机的短期存储器,用于存储正在运行的程序和数据。它的访问速度非常快,比磁盘快几个数量级。在分布式计算中,内存用于缓存中间结果、存储…

Jenkins linux安装

jenkins启动 service jenkins start 重启 service jenkins restart 停止 service jenkins stop jenkins安装 命令切换到自己的下载目录 直接用命令下载 wget http://pkg.jenkins-ci.org/redhat-stable/jenkins-2.190.3-1.1.noarch.rpm 下载直接安装 rpm -ivh jenkins-2.190.3-…

RabbitMQ ②-工作模式

RabbitMQ 工作模式 官方提供了七种工作模式 Simple(简单模式) P:生产者,发布消息到队列C:消费者,从队列中获取消息并消费Queue:消息队列,存储消息。 一个生产者,一个…

(2)python开发经验

文章目录 1 pyside6加载ui文件2 使用pyinstaller打包 更多精彩内容👉内容导航 👈👉Qt开发 👈👉python开发 👈 1 pyside6加载ui文件 方法1: 直接加载ui文件 from PySide6.QtWidgets import QAp…

【C++】互斥锁(Mutex)

在C中,互斥锁(Mutex)是用于线程同步的重要工具,用于保护共享资源,防止多线程同时访问导致的数据竞争(Data Race)问题。 以下是C中互斥锁的核心用法和示例: 一、基本互斥锁 std::mut…

Jsoup与HtmlUnit:两大Java爬虫工具对比解析

Jsoup:HTML解析利器 定位:专注HTML解析的轻量级库(也就是快,但动态页面无法抓取) 核心能力: DOM树解析与CSS选择器查询 HTML净化与格式化 支持元素遍历与属性提取 应用场景:静态页面数据抽…

小白成长之路-vim编辑

文章目录 Vim一、命令模式二、插入模式3.a:进入插入模式,在当前光标的后一个字符插入![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/fd293c3832ed49e2974abfbb63eeb5bb.png)4.o: 在当前光标的下一行插入5.i:在当前光标所在字符插入,返回命令模…

[redis进阶六]详解redis作为缓存分布式锁

目录 一 什么是缓存 缓存总结板书: 二 使⽤Redis作为缓存 三 缓存的更新策略 1) 定期⽣成 2) 实时⽣成 四 面试重点:缓存预热,缓存穿透,缓存雪崩 和缓存击穿 1)缓存预热 2)缓存穿透 3)缓存雪崩 4)缓存击穿 五 分布式锁 板书: 1)什么是分布式锁 2)分布式锁的基…

【MySQL】数据表插入数据

个人主页:Guiat 归属专栏:MySQL 文章目录 1. 插入数据概述1.1 插入数据的重要性1.2 插入数据的基本原则 2. 基本插入语句2.1 INSERT INTO语法2.2 插入多行数据2.3 不指定列名的插入2.4 插入NULL和默认值 3. 高级插入技术3.1 使用子查询插入数据3.2 IGNOR…

软考-软件设计师中级备考 14、刷题 算法

一、考点归纳 1)排序 2、查找 3、复杂度 4、经典问题 0 - 1 背包动态规划0 - 1 背包问题具有最优子结构性质和重叠子问题性质。通过动态规划可以利用一个二维数组来记录子问题的解,避免重复计算,从而高效地求解出背包能装下的最大价值。分…

【阿里云】阿里云 Ubuntu 服务器无法更新 systemd(Operation not permitted)的解决方法

零、前言 目前正在使用的Ubuntu服务器中,仅阿里云(不止一台)出现了这个问题,因此我判定是阿里云服务器独有的问题。如果你的服务器提供商不是阿里云,那么这篇文章可能对你没有帮助。 如果已经因为升级错误导致依赖冲突…

css 点击后改变样式

背景: 期望实现效果:鼠标点击之后,保持选中样式。 实现思路:在css样式中,:active 是一种伪类,用于表示用户当前正在与被选定的元素进行交互。当用户点击或按住鼠标时,元素将被激活,此…

采用AI神经网络降噪算法的语言降噪消回音处理芯片NR2049-P

随着AI时代来临.通话设备的环境噪音抑制也进入AI降噪算法时代. AI神经网络降噪技术是一款革命性的语音处理技术,他突破了传统单麦克风和双麦克风降噪的局限性,利用采集的各种日常环境中的噪音样本进行训练学习.让降噪算法具有自适应噪声抑制功能,可以根…

不用联网不用编程,PLC通过智能网关快速实现HTTP协议JSON格式与MES等系统平台双向数据通讯

智能网关IGT-DSER集成了多种PLC的原厂协议,方便实现各种PLC、智能仪表通过HTTP协议与MES等各种系统平台通讯对接。PLC内不用编写程序,设备不用停机,通过网关的参数配置软件(下载地址)配置JSON文件的字段与PLC寄存器地址等参数即可。 …

如何将两台虚拟机进行搭桥

将两台虚拟机实现网络互通(“搭桥”)需配置虚拟网络,以下是基于 VMware Workstation 和 VirtualBox 的详细操作指南(以 Windows 系统为例,Linux 原理类似): 一、VMware Workstation 配置&#x…