首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

破解 Kotlin 协程(3) - 协程调度篇

关键词:Kotlin 异步编程 协程 上一篇我们知道了协程启动的几种模式,也通过示例认识了 launch 启动协程的使用方法,本文将延续这些内容从调度的角度来进一步为大家揭示协程的奥义。 ? 1....协程上下文 调度器本质上就是一个协程上下文的实现,我们先来介绍下上下文。...首先,所有协程启动的时候,都会有一次 Continuation.resumeWith 的操作,这一次操作对于调度器来说就是一次调度的机会,我们的协程有机会调度到其他线程的关键之处就在于此。...3.4 线程安全问题 Js 和 Native 的并发模型与 Jvm 不同,Jvm 暴露了线程 API 给用户,这也使得协程的调度可以由用户更灵活的选择。...越多的自由,意味着越多的代价,我们在 Jvm 上面编写协程代码时需要明白一点的是,线程安全问题在调度器不同的协程之间仍然存在。

76920
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Kotlin协程解析系列(上):协程调度与挂起

    vivo 互联网客户端团队- Ruan Wen 本文是Kotlin协程解析系列文章的开篇,主要介绍Kotlin协程的创建、协程调度与协程挂起相关的内容 一、协程引入 Kotlin 中引入 Coroutine...协程“同步方式写出异步代码”的这个特性就可以很好的解决上述问题。...调度的本质就是解决挂起点恢复之后的协程逻辑在哪里运行的问题。调度器也属于协程上下文一类,它继承自拦截器。...除了上述的方法,kotlin协程还给出了更简单的api,如下: 图片 前述我们是通过线程的方式,同理可以通过线程池转为调度器实现。...协程拦截器的实现就是拦截Continuation,可在此处进行缓存、日志打印等拦截处理。 调度器即确认相关协程在哪个线程上执行,调度的本质是解决挂起恢复后协程逻辑在哪里运行的问题,其继承自拦截器。

    2K40

    【Kotlin 协程】协程底层实现 ② ( 协程调度器 | 协程任务泄漏 | 结构化并发 )

    文章目录 一、协程调度器 二、协程任务泄漏 三、结构化并发 一、协程调度器 ---- 协程 是在 调度器 中运行的 , 在协程中有 3 种调度器 : Dispatchers.Main 调度器 : 在 主线程...是不同的 , 需要采用不同的任务取消策略 , 因此这里将耗时任务分配成两种调度器 ; 二、协程任务泄漏 ---- 协程任务泄漏 : 发起 协程任务 后 , 无法追踪任务的执行结果 , 任务等于无效任务..., 但是仍然会消耗 内存 , CPU , 网络 , 磁盘 等资源 ; Kotlin 中引入了 结构化并发机制 避免 协程任务泄漏 的情况发生 ; 协程任务泄漏 与 内存泄漏 类似 ; 三、结构化并发...---- 结构化并发 使用场景 : 协程任务取消 : 在不需要协程任务的时候 , 取消协程任务 ; 追踪协程任务 : 追踪正在执行的协程任务 ; 发出错误信号 : 如果 协程任务执行失败 , 发出错误信号..., 表明执行任务出错 ; 协程任务 运行时 , 必须指定其 CoroutineScope 协程作用域 , 其会追踪所有的 协程任务 , CoroutineScope 协程作用域 可以取消 所有由其启动的协程任务

    70420

    Kotlin协程-特殊的阻塞协程

    首先是父协程得到执行,然后才是子协程。 重点是这两段协程都在同一个线程main里完成。这里就带来一个有趣的问题, runBLocking{}和平时常用的launch有什么区别?...这里给出结果,改用GlobalScope.launch之后,子协程会在一个独立的线程里运行。 runBlocking 在kotlin协程官网上对于这个api的解释是桥接阻塞与非阻塞的世界。...没有的话就使用默认的eventloop。EventLoop是协程里对阻塞型coroutine进行调度的默认调度器。runBlocking和launch的主要区别就靠EventLoop实现。...在创建完coroutine后就进入派发流程了,这部分和Kotlin协程-一个协程的生命周期中的逻辑比较相似,下面也会讲到。...猜测是为了避免协程嵌套太多,导致stack over flow的问题出现。

    2.5K20

    go一个协程安全协程调度的问题

    这是因为 main协程和 子协程共享变量造成的问题,主要执行流程如下: package main import "time" func main() {    var testNum = 0    ...这就涉及到了go的协程调度问题了,具体是怎么调度的呢?...go的协程调度 go的协程调度为 [典藏版] Golang 调度器 GMP 原理与调度全分析 简单说明: G:协程 M:运行的线程 P:执行线程的处理器,可以理解为cpu中的线程/进程 - 在运行时,...,则变成了100%输出 testNum=1: 刚刚我们看到了GMP的第一点,有多少个P,就应该有多少个M/G同时运行,那么问题来了,为什么上面的2个协程没有并行呢?...如果M没有可以执行的G后,将会偷其他M的G 在示例代码,由于是先执行的go func,sleep(协程2),所以M在执行main开始之后,立即开始执行协程2,同时由于协程2 sleep阻塞,所以切回main

    68840

    破解 Kotlin 协程(5) - 协程取消篇

    关键词:Kotlin 协程 协程取消 任务停止 协程的任务的取消需要靠协程内部调用的协作支持,这就类似于我们线程中断以及对中断状态的响应一样。 1. 线程的中断 我们先从大家熟悉的话题讲起。...再谈 Retrofit 的协程扩展 4.1 Jake Wharton 的 Adapter 存在的问题 我在破解 Kotlin 协程 - 入门篇(https://www.bennyhuo.com/2019...,它的构造可接受一个 Job 实例作为它的父协程,那么问题来了,这里并没有告诉它父协程究竟是谁,因此也就谈不上作用域的事儿了,这好像我们用 GlobalScope.launch 启动了一个协程一样。...最后我们还分析了一下 Retrofit 的协程扩展的一些问题和解决方法,这个例子也进一步可以引发我们对协程作用域以及如何将现有程序协程化的思考。...再稍微提一句,协程不是一个简单的东西,毕竟它的原理涉及到对操作系统调度、程序运行机制这样程序界毕竟原始的话题,但你说如果我对前面提到的这些都不是很熟悉或者根本没有接触过,是不是就要跟协程拜拜了呢,其实也不是

    1.8K50

    Kotlin 协程的上下文和调度器介绍-Dispatchers

    介绍 协程的上下文通常是CoroutineContext类型为代表。这个类型是被定义在Kotlin的标准库中。 在协程中,上下文是各种不同元素的集合。而其中主导作用的元素就是Job。...我们在了解协程的并发与调度的时候涉及到了Job。Kotlin 协程 组合挂起函数和async关键字,实现协程的并发操作 (zinyan.com) 这篇继续深入了解Job。...非受限的调度器是一种高级机制,可以在某些极端情况下提供帮助而不需要调度协程以便稍后执行或产生不希望的副作用, 因为某些操作必须立即在协程中执行。非受限调度器不应该在通常的代码中使用。...并且这个新协程的Job对象将会成为父协程的子Job对象。 当一个父协程被取消的时候,所有它的子协程也会被递归的取消。 但是,当使用 GlobalScope 来启动一个协程时,则新协程的作业没有父作业。...Kotlin 提供了:ThreadLocal,asContextElement 扩展函数来帮助我们,它们创建了额外的上下文元素, 且保留给定 ThreadLocal 的值,并在每次协程切换其上下文时恢复它

    45810

    java协程框架quasar和kotlin中的协程

    协程不同于线程,线程是操作系统级别的资源,创建线程,调度线程,销毁线程都是重量级别的操作。而且线程的资源有限,在java中大量的不加限制的创建线程非常容易将系统搞垮。...,他标记了协程代码的起始和结束的位置,以及方法需要暂停的位置,每个协程任务统一由FiberScheduler去调度,内部维护了一个或多个ForkJoinPool实例。...而反观协程,基于固定的几个线程调度,可以轻松实现百万级的协程处理,而且内存稳稳的。 后记 最后,博主以为Quasar只是一个框架层面的东西,所以就又去看了下同样是jvm语言的kotlin的协程。...,有种震惊的赶脚,kotlin的同步模型牛逼呀,瞬时感觉到发现了java里的骚操作了,可以使用kotlin的协程来代替java中的多线程操作。...io操作,io操作是阻塞的,协程的并发也就变成了调度协程的几个线程的并发了。

    54430

    【Kotlin 协程】协程的挂起和恢复 ② ( 协程挂起 和 线程阻塞 对比 )

    文章目录 一、协程挂起 和 线程阻塞 对比 1、协程挂起 2、线程阻塞 3、挂起和阻塞对 UI 的影响 4、挂起分析 一、协程挂起 和 线程阻塞 对比 ---- 挂起是协程中的概念 , 只能在协程中使用...; 阻塞是线程中的概念 , 可以在主线程和子线程中使用 ; 1、协程挂起 协程 挂起 操作 : 在协程中使用 delay 函数 , 挂起 20 秒时间 , 然后 20 秒后更新 UI ; delay...函数是 挂起 suspend 函数 ; // 创建协程 GlobalScope.launch(Dispatchers.Main) { delay(20000) // 主线程更新 UI...协程 挂起 操作 不会出现 阻塞 UI 刷新的情况 , 挂起的 20 秒不影响 UI 刷新显示 ; 但是如果将主线程阻塞 , UI 不再刷新 , 会出现 ANR 崩溃异常 ; 图形化 GUI 系统中..., 会将挂起点的状态保存 , 同时协程停止执行 , 等待挂起函数执行完毕后 , 协程继续执行 ; 相当于阻塞的是协程 , 不会阻塞主线程 ;

    1.8K20

    Kotlin---协程的使用

    第一个协程 在使用协程之前,需要保证Kotlin-Gradle-Plugin的版本高于1.3。目前最高的版本为1.3.11。...并且这样执行的协程,并不会阻塞主线程的执行 delay函数只能在协程中使用,否则编译不过,尽量避免使用GlobalScope.launch创建协程,当我们使用 GlobalScope.launch 时...如果我们忘记保持对新启动的协程的引用,它还会继续运行。 阻塞的协程runBlocking GlobalScope.launch启动了一个线程创建新的协程,并没有阻塞当前线程。...val job = GlobalScope.launch { // 启动一个新协程并保持对这个作业的引用 delay(1000L) println("Hello,......,会等待coroutineScope中的协程都执行完毕后,才会继续执行 挂起函数 当协程中的代码超级多的时候,通常都会把这些代码提取到一个函数中。

    1.3K20

    关于 Kotlin Coroutines, 你可能会犯的 7 个错误

    在我看来,Kotlin Coroutines(协程) 大大简化了同步和异步代码。...但是,我发现了许多开发者在使用协程时会犯一些通用性的错误。 1. 在使用协程时实例化一个新的 Job 实例 有时候你会需要一个 job 来对协程进行一些操作,例如,稍后取消。...所以你创建的新协程的父 job 并不是协程作用域的 job,而是新创建的 job 对象。 因此,协程的 job 和协程作用域的 job 此时并没有什么关联。...一些开发者认为当调用协程时,就应该切换到后台调度器,例如,进行网络请求的 Retrofit 的 suspend 函数,进行数据库操作的 Room 的 suspend 函数。 这并不是必须的。...关于 Kotlin 协程异常处理最不直观的方面之一是,你不能使用 try-catch 来捕获异常。

    99820

    Kotlin 学习笔记(四)—— 协程的基础知识,面试官的最爱了~

    协程是什么 协程是一种编程思想。它并不局限于任何语言,不仅 Kotlin 中有对协程的实现,Python、Go 等语言也有。...它的设计初衷就是为了解决并发问题,可以更方便地处理多线程协作的任务。 在 Kotlin 中,协程就是一个封装好的线程框架。...3.2 协程调度器 在 3.1 中已经出现过调度器的身影,就是当需要指定协程运行的线程时,使用调度器调度即可。在实际的使用中是通过 Dispatchers 对象来访问它们。...立即调度:指的是协程的调度器会立刻接收到调度指令,但具体什么时候调度线程执行,还需要根据调度器的具体情况而定,即立即调度到立即执行之间通常会有时间间隔。...await 方法后才会开始调度,在执行前如果被取消则将直接进入异常结束状态; ATOMIC:表示该协程创建后,立即开始调度,且调度和执行合二为一,是原子操作,协程一定会执行,不会被取消掉,只能忽略协程的执行结果

    1.6K30

    【Kotlin 协程】协程的挂起和恢复 ① ( 协程的挂起和恢复概念 | 协程的 suspend 挂起函数 )

    文章目录 一、协程的挂起和恢复概念 二、协程的 suspend 挂起函数 一、协程的挂起和恢复概念 ---- 函数 最基本的操作 是 : 调用 call : 通过 函数名或函数地址 调用函数 ; 返回...return : 函数执行完毕后 , 继续执行函数调用的下一行代码 ; 协程 在 调用 call 和 返回 return 基础上 , 又新增了两种 状态 : 挂起 Suspend : 暂停当前执行的协程..., 在子线程中执行异步任务后 , 会马上执行后续的代码 , 只是相当于 普通的多线程操作 ; 协程的作用就是 可以 顺序地执行 异步任务 和 主线程任务 , 其执行顺序按照代码顺序执行 ; 挂起 函数..., 只能在 协程体内部 或者 其它挂起函数 中调用 ; 协程外部不允许使用挂起函数 ; 在协程中 , 执行 挂起 Suspend 函数 , 将 挂起点的信息 记录下来 , 然后执行耗时操作 , 执行完毕后...){} 中 , 可以直接调用挂起函数 ; 挂起 函数 , 只能在 协程体内部 或者 其它挂起函数 中调用 ; 协程外部不允许使用挂起函数 ; 在协程中 , 执行 挂起 Suspend 函数 , 将 挂起点的信息

    1.7K40

    Kotlin---使用协程的异步

    协程间的通信 协程与协程间不能直接通过变量来访问数据,会导致数据原子性的问题,所以协程提供了一套Channel机制来在协程间传递数据。...所以这里保证所有先前发送出去的元素都在通道关闭前被接收到。 基于协程的生产者\消费者 在协程中,可以通过produce来模拟生产者生产数据。并且通过consume来模拟消费者情况。...它启动了一个单独的协程,这是一个轻量级的线程并与其它所有的协程一起并发的工作。...、被限制并封装到该协程中的状态以及一个与其它协程通信的 通道 组合而成的一个实体。...一个 actor 是一个协程,而一个协程是按顺序执行的,因此将状态限制到特定协程可以解决共享可变状态的问题。实际上,actor 可以修改自己的私有状态,但只能通过消息互相影响(避免任何锁定)。

    2.8K20

    揭秘kotlin协程中的CoroutineContext

    前言 -- 从kotlin1.1开始,协程就被添加到kotlin中作为实验性功能,直到kotlin1.3,协程在kotlin中的api已经基本稳定下来了,现在kotlin已经发布到了1.4,为协程添加了更多的功能并进一步完善了它...,所以我们现在在kotlin代码中可以放心的引入kotlin协程并使用它,其实协程并不是kotlin独有的功能,它是一个广泛的概念,协作式多任务的实现,除了kotlin外,很多语言如Go、Python等都通过自己的方式实现了协程...协程的实现依赖于线程,它不能脱离线程而存在,因为线程才是CPU调度的基本单位,协程通过程序的调度可以执行在一个或多个线程之中,所以协程需要运行于线程之中,由于协程是由程序自己调度的,所以程序就需要实现调度逻辑...,不同语言的调度的实现不一样,在kotlin中,通过Dispatcher来调度协程,而Dispatcher它通常是一个线程池的实现或者基于特定平台(例如Android)主线程的实现,通过调度让协程运行于一个或多个线程之中...上面就是我对协程的简单理解,总的来说:协程需要线程的承载运行,协程需要程序自己完成调度,协程让你更容易写出协作式任务。

    1.9K31
    领券