聊聊structure concurrency 结构化并发

前面我们谈了,coroutine的coroutineScope继承异常处理取消,也在文中提到了他们和structure concurrency的特性,想必大家都已经有一点基本概念。

这篇文章,主要会先讨论为甚麽coroutine要用structure concurrency,是要解决什麽问题,之後复习一下那些提过的特性,帮大家把我的文章前後连贯起来。

为什麽用structure concurrency

在讨论为什麽用之前,不如先谈谈如果不用会怎样?
假设今天我在需要发出100个请求,(官方blog是举例1000啦,但我觉得二位数後都很麻烦),我就需要手动追踪所有的coroutine,检查Exception,更甚者当我们要取消剩余任务时,也需要针对全数进行检查状态和取消。

如果今天,粗心了忘记取消某个coroutine任务,就会work Leak,那work leak是什麽?

他和memory leak的共通点就是都会占用内存,而work leak更糟糕,他有可能在背後更改到资料库、发出网路请求,占用cpu资源等等,而coroutine的开发者针对这种问题,引入了Structure concurrency,以达到下列三点

  1. 不需要时自动取消任务
  2. 在运行时自动追踪任务
  3. 当coroutine执行失败时 throw Exception

而在kotlin coroutine里面,分别以下列特性展现

  1. 当一个coroutineScope取消时,所有他之下的Job都会连带取消
  2. suspend fun 确保他返回时,所有内部工作都已完成
  3. 当一个coroutine throw Exception,他的parent coroutine或caller会被通知

看着熟悉吧,就是前面我讲过的那些,既然已经懂了为什麽要用structure concurrency,现在来复习一下吧

在kotlin里,所有的coroutine都必须在coroutineScope里面运行,而开启一个coroutineScope的方式有下面几种

  1. CoroutineScope -自己客制一个
  2. GlobalScope -跟着application生命周期的
  3. MainScope -supervisorJob() + Dispatcher.Main
  4. lifecycleScope -跟着fragment/activity lifecycleScope生命周期的
  5. viewModelScope -跟着viewModel lifecycleScope生命周期的
  6. runBlocking - 测试用的

cancel with structure concurrency

当我们创建了coroutineScope後,它会自动追踪在该作用域的每个coroutine,可透过launch/async开启coroutine,而coroutine的取消是透过 throw CancellationException来取消,取消的行为,只会影响自身跟子coroutine,对parent和sibiling不会有影响

这个特性,不只是Job.cancel()适用,Scope.cancel()也同样套用这个规则,为了便於管理,我们经常会在一个scope里面建立多个coroutine执行任务,那当我们不再需要那些任务执行时,只需要对scope呼叫cancel()即可,它会自动取消依附於他之下的coroutine

Structured concurrency guarantees when a scope cancels, all of its coroutines cancel.

Exception with structure concurrency

Structured concurrency guarantees that when a coroutine errors, its caller or scope is notified.

记得之前讲过的Exception如何传递的吧,这边就简单复习一下,当一个coroutine throw Exception,他会通知她的parent,parent会再通知parent的parent,直到root,再全部取消

如果希望coroutine 出异常时,其他coroutine能继续执行任务,应当使用supervisorJob或supervisorScope,并妥善处理Exception,具体资讯都写在这里

追踪coroutine

另一个结构化病发的特点就是追踪,在coroutineScope或supervisorScope里面的coroutine,会被自动追踪

范例是已发出1000个请求,其实不论launch/async,都只会在所有coroutine都完成工作後才会回传,从而避免了work leak

连结
官方blog


<<:  【Day10】AddInvitationFragment(下) X DatePickerDialog

>>:  Day10 OLED进化成Micro OLED後来找Micro LED报仇了!?

D3 - 今天点个 String Methods 套餐

前言 今天来讲讲 String Methods,你知道其实除了length 以外,String 还内...

[Java Day08] 3.1. if else

教材网址 https://coding104.blogspot.com/2021/06/java-i...

从听明牌,学习投资

获取明牌,并不一定就是赌徒心态;正确的观念是,应该是要先了解,人家何会推荐这只?是从基本面?消息面?...

Android Studio初学笔记-Day20-AlertDialog(1)

AlertDialog(对话窗功能) AlertDialog很常在提示或者再次确认资料时看见,其功能...

IT铁人DAY 25-Iterator 迭代器模式

  今天要认识的迭代器模式我个人觉得需要多花一点心思,才能够了解它并善用它,程序当中也算是经常使用的...