协程的定义
官方链接中文版 据官方描述协程是一个轻量级的线程,但是可能很多人不太理解这句话的意思,对于线程来说,何谓线程?
线程
线程是我们CPU运行的最小单元百度描述 那么官方描述所谓的轻量级线程可能就比较难以明白了!线程已经是最小的运行单元,怎么轻量级了?一开始可能就被这个轻量级带跑路了…
协程(个人理解)
协程依然是一个线程框架,依然是基于线程来封装的一套api ,原来对于线程的内容依然能用在协程中),而不同于线程的东西而言,协程的api重点在于不是如何去控制线程,而是类似线程一样的方式去控制任务!将任务进行细粒度的分割成伪线程的状态; 所以你理解线程和协程的区别时,不要把协程当成线程来对待,否则你可能被协程中的api迷惑!
区别
- 线程是内核里的东西,而协程是基于用户的(程序员)
- 线程是cpu分配时间片段需要执行上下文的切换(不同线程的切换),协程上下文的切换只是任务的切换,而线程有可能是不会切换的(单线程不会)
挂起与阻塞
挂起不是阻塞,挂起举个简单的例子,A,B 两个任务,如果我要去做 A任务做一半的时候如果领导说现在先完成B 那么我先把B执行 做完再去A 而阻塞好比我做A 领导要去去做B 我说不行 手上的A 没完成 ,等我做完A 那么B一直会被等待
那么对于线程来说我们的cpu对于协程而言当得到时间片段的时候依然能继续运行 线程阻塞来说就是浪费了这段时间片段
所以协程的一大优点就是解决了CPU资源浪费的问题
start
HellowWorld-Kotlin
fun main() = runBlocking<Unit> {
println(Thread.currentThread().name)
launch { // launch a new coroutine and continue
// delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!${System.currentTimeMillis()}") // print after delay
println(Thread.currentThread().name)
}
println("Hello${System.currentTimeMillis()}") // mai
}
//s
我们输出线程名称结果如下: 发现协程也是运行在main线程的.ok到此我们可以更容易理解 我们的协程了
协程上下文CoroutineContext
协程上下文是一个抽象的概念, 从API上来看 协程上下文提供的是对元素Element的操作
get
fold
那么我们看下Element也就是我们上下文的元素
Element
- public interface Job : CoroutineContext.Element
- interface ContinuationInterceptor : CoroutineContext.Element
- AbstractCoroutineContextElement
- ThreadContextElement
我们暂时列举这几个,不难发现我们协程上下文就是封装了一系列的元素,也就是我们协程上的组件
协程的启动
协程的启动必须依赖于协程上下文去启动
在协程中提供了几种启动方式 如下:
MainScope
GlobalScope
runBlocking
从源码中我们可以发现的是都是根据协程上下文去启动的
|