Kotlin 協(xié)程(四) -協(xié)程上下文與調(diào)度器

Kotlin 協(xié)程(一)

Kotlin 協(xié)程?(二)協(xié)程取消與超時(shí)

Kotlin 協(xié)程(三) async和await

所有的協(xié)程都是在上下文中運(yùn)行,而協(xié)程上下文包含一個(gè)協(xié)程調(diào)度器.

協(xié)程調(diào)度器確定了相關(guān)的協(xié)程在哪個(gè)線程或哪些線程上執(zhí)行,協(xié)程調(diào)度器可以將協(xié)程限制在一個(gè)特定的線程執(zhí)行,或?qū)⑺峙傻揭粋€(gè)線程池,亦或是讓它不受限地運(yùn)行.

協(xié)程調(diào)度器源碼:

public actual object Dispatchers {

????/**

?????* The default [CoroutineDispatcher] that is used by all standard builders like

?????* [launch][CoroutineScope.launch], [async][CoroutineScope.async], etc

?????* if no dispatcher nor any other [ContinuationInterceptor] is specified in their context.

?????*

?????* It is backed by a shared pool of threads on JVM. By default, the maximal level of parallelism used

?????* by this dispatcher is equal to the number of CPU cores, but is at least two.

?????* Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel.

?????*/

????@JvmStatic

????public actual val Default: CoroutineDispatcher = createDefaultDispatcher()

????/**

?????* A coroutine dispatcher that is confined to the Main thread operating with UI objects.

?????* This dispatcher can be used either directly or via [MainScope] factory.

?????* Usually such dispatcher is single-threaded.

?????*

?????* Access to this property may throw [IllegalStateException] if no main thread dispatchers are present in the classpath.

?????*

?????* Depending on platform and classpath it can be mapped to different dispatchers:

?????* - On JS and Native it is equivalent of [Default] dispatcher.

?????* - On JVM it is either Android main thread dispatcher, JavaFx or Swing EDT dispatcher. It is chosen by

?????*???[`ServiceLoader`](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html).

?????*

?????* In order to work with `Main` dispatcher, the following artifacts should be added to project runtime dependencies:

?????*??- `kotlinx-coroutines-android` for Android Main thread dispatcher

?????*??- `kotlinx-coroutines-javafx` for JavaFx Application thread dispatcher

?????*??- `kotlinx-coroutines-swing` for Swing EDT dispatcher

?????*

?????* In order to set a custom `Main` dispatcher for testing purposes, add the `kotlinx-coroutines-test` artifact to

?????* project test dependencies.

?????*

?????* Implementation note: [MainCoroutineDispatcher.immediate] is not supported on Native and JS platforms.

?????*/

????@JvmStatic

????public actual val Main: MainCoroutineDispatcher get() = MainDispatcherLoader.dispatcher

????/**

?????* A coroutine dispatcher that is not confined to any specific thread.

?????* It executes initial continuation of the coroutine in the current call-frame

?????* and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without

?????* mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid

?????* stack overflows.

?????*

?????* ### Event loop

?????* Event loop semantics is a purely internal concept and have no guarantees on the order of execution

?????* except that all queued coroutines will be executed on the current thread in the lexical scope of the outermost

?????* unconfined coroutine.

?????*

?????* For example, the following code:

?????* ```

?????* withContext(Dispatchers.Unconfined) {

?????*????println(1)

?????*????withContext(Dispatchers.Unconfined) { // Nested unconfined

?????*????????println(2)

?????*????}

?????*????println(3)

?????* }

?????* println("Done")

?????* ```

?????* Can print both "1 2 3" and "1 3 2", this is an implementation detail that can be changed.

?????* But it is guaranteed that "Done" will be printed only when both `withContext` are completed.

?????*

?????*

?????* Note that if you need your coroutine to be confined to a particular thread or a thread-pool after resumption,

?????* but still want to execute it in the current call-frame until its first suspension, then you can use

?????* an optional [CoroutineStart] parameter in coroutine builders like

?????* [launch][CoroutineScope.launch] and [async][CoroutineScope.async] setting it to the

?????* the value of [CoroutineStart.UNDISPATCHED].

?????*/

????@JvmStatic

????public actual val Unconfined: CoroutineDispatcher = kotlinx.coroutines.Unconfined

????/**

?????* The [CoroutineDispatcher] that is designed for offloading blocking IO tasks to a shared pool of threads.

?????*

?????* Additional threads in this pool are created and are shutdown on demand.

?????* The number of threads used by this dispatcher is limited by the value of

?????* "`kotlinx.coroutines.io.parallelism`" ([IO_PARALLELISM_PROPERTY_NAME]) system property.

?????* It defaults to the limit of 64 threads or the number of cores (whichever is larger).

?????*

?????* Moreover, the maximum configurable number of threads is capped by the

?????* `kotlinx.coroutines.scheduler.max.pool.size` system property.

?????* If you need a higher number of parallel threads,

?????* you should use a custom dispatcher backed by your own thread pool.

?????*

?????* This dispatcher shares threads with a [Default][Dispatchers.Default] dispatcher, so using

?????* `withContext(Dispatchers.IO) { ... }` does not lead to an actual switching to another thread —

?????* typically execution continues in the same thread.

?????*/

????@JvmStatic

????public val IO: CoroutineDispatcher = DefaultScheduler.IO

}

從源碼可以得知

Main 是運(yùn)行在主線程的及在Android中進(jìn)行UI繪制的線程.一般用于處理UI繪制及一些輕量級(jí)任務(wù)

Default 是運(yùn)行在非主線程的,一般用于CPU密集型計(jì)算型任務(wù).如數(shù)組排序,JSON解析,異常判斷等

IO 是運(yùn)行在非主線程的,一般用于磁盤(pán)操作和網(wǎng)絡(luò)IO操作任務(wù).如數(shù)據(jù)庫(kù)操作,文件讀寫(xiě),網(wǎng)絡(luò)請(qǐng)求等

Unconfined 未定義的線程,是一個(gè)特殊的調(diào)度器且似乎也運(yùn)行在 main 線程中,但實(shí)際上它是一種不同的機(jī)制.協(xié)程調(diào)度器在調(diào)用它的線程啟動(dòng)了一個(gè)協(xié)程,但它僅僅只是運(yùn)行到第一個(gè)掛起點(diǎn).掛起后,它恢復(fù)線程中的協(xié)程,而這完全由被調(diào)用的掛起函數(shù)來(lái)決定.非受限的調(diào)度器非常適用于執(zhí)行不消耗 CPU 時(shí)間的任務(wù),以及不更新局限于特定線程的任何共享數(shù)據(jù)(如UI)的協(xié)程

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子替裆,更是在濱河造成了極大的恐慌汇恤,老刑警劉巖幢踏,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件光稼,死亡現(xiàn)場(chǎng)離奇詭異步鉴,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)斥赋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)缰猴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人疤剑,你說(shuō)我怎么就攤上這事滑绒∶票ぃ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵疑故,是天一觀的道長(zhǎng)杠览。 經(jīng)常有香客問(wèn)我,道長(zhǎng)纵势,這世上最難降的妖魔是什么踱阿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮钦铁,結(jié)果婚禮上软舌,老公的妹妹穿的比我還像新娘。我一直安慰自己牛曹,他們只是感情好佛点,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著黎比,像睡著了一般超营。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阅虫,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天演闭,我揣著相機(jī)與錄音,去河邊找鬼颓帝。 笑死船响,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的躲履。 我是一名探鬼主播见间,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼工猜!你這毒婦竟也來(lái)了米诉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤篷帅,失蹤者是張志新(化名)和其女友劉穎史侣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體魏身,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惊橱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了箭昵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片税朴。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出正林,到底是詐尸還是另有隱情泡一,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布觅廓,位于F島的核電站鼻忠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏杈绸。R本人自食惡果不足惜帖蔓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瞳脓。 院中可真熱鬧讨阻,春花似錦、人聲如沸篡殷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)板辽。三九已至,卻和暖如春棘催,著一層夾襖步出監(jiān)牢的瞬間劲弦,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工醇坝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邑跪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓呼猪,卻偏偏與公主長(zhǎng)得像画畅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宋距,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容