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

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.xdnf.cn/news/5645.html

相关文章:

  • 智能SQL优化工具集成:从概念到实践
  • 面试篇:Spring MVC
  • C++多态讲解
  • 【Redis】分布式锁的实现
  • Excel分组计算求和的两种实现方案
  • 【Python】Python常用数据类型判断方法详解
  • K8S中构建双架构镜像-从零到成功
  • Go语言爬虫系列教程(一) 爬虫基础入门
  • 新能源汽车电池加热技术:传统膜加热 vs. 脉冲自加热
  • Porting Linux to a new processor architecture, part 1: The basics
  • 异步FIFO的学习
  • Linux 上安装RabbitMQ
  • android14优化ntp时间同步
  • 全栈工程师实战手册:LuatOS日志系统开发指南!
  • Matlab 垂向七自由度轨道车辆开关型半主动控制
  • Spring Boot集成RabbitMQ高级篇:可靠性与性能提升
  • OpenHarmony Linux内核本地管理
  • 网络爬虫学习之正则表达式
  • Edge浏览器打开PDF文件显示空白(每次需要等上一会)
  • FPGA前瞻篇-计数器设计与实现实例
  • Spark SQL 运行架构详解(专业解释+番茄炒蛋例子解读)
  • Mosaic数据增强技术
  • 大规模k8s集群怎么规划
  • Spring IoCDI
  • matlab simulink双边反激式变压器锂离子电池均衡系统,双目标均衡策略,仿真模型,提高均衡速度38%
  • 大语言模型训练的两个阶段
  • 神经网络是如何工作的
  • Linux 文件权限管理
  • 【Leetcode】系列之206反转链表
  • 工具篇-如何在Github Copilot中使用MCP服务?