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
意思是他們三個其實是一個對象