Kotlin協(xié)程探索 (一)(Coroutine)
PS:以下協(xié)程都特指Kotlin協(xié)程司澎;且期望大家大概知道協(xié)程的寫法;
- 什么是協(xié)程重荠?
- 協(xié)程箭阶?線程?優(yōu)勢戈鲁?
什么是協(xié)程仇参?
引用官方的話就是
本質(zhì)上,協(xié)程是輕量級(jí)的線程婆殿。 它們?cè)谀承?CoroutineScope 上下文中與 launch 協(xié)程構(gòu)建器 一起啟動(dòng)诈乒。 這里我們?cè)?GlobalScope 中啟動(dòng)了一個(gè)新的協(xié)程,這意味著新協(xié)程的生命周期只受整個(gè)應(yīng)用程序的生命周期限制婆芦。
可以將 GlobalScope.launch { …… } 替換為 thread { …… }怕磨,并將 delay(……) 替換為 Thread.sleep(……) 達(dá)到同樣目的喂饥。 試試看(不要忘記導(dǎo)入 kotlin.concurrent.thread)。
個(gè)人看法
協(xié)程是線程內(nèi)自主可控的任務(wù)集肠鲫,不需要等待系統(tǒng)切換線程進(jìn)行調(diào)度仰泻,從而輕量化線程的操作,請(qǐng)看下圖
協(xié)程滩届?線程?優(yōu)勢被啼?
栗子帜消,最基本樣子,沒什么可比性
fun main(args: Array<String>) = runBlocking<Unit> {
thread {
println("開啟一個(gè)線程")
}
launch {
println("開啟一個(gè)協(xié)程")
}
}
繼續(xù)浓体,當(dāng)出現(xiàn)耗時(shí)操作泡挺,由于Kotlin協(xié)程內(nèi)部使用線程池,為了公平起見命浴,有了以下兩個(gè)栗子
- 線程
fun main(args: Array<String>) = runBlocking<Unit> {
//4個(gè)線程
time { //統(tǒng)計(jì)運(yùn)行時(shí)間
val threadPool = Executors.newScheduledThreadPool(4)
repeat(100) {
threadPool.submit {
Thread.sleep(500)
println("thread println $it")
}
}
threadPool.shutdown()
threadPool.awaitTermination(100, TimeUnit.SECONDS)
}.println()
}
- 協(xié)程
fun main(args: Array<String>) = runBlocking<Unit> {
//4個(gè)線程
time { //統(tǒng)計(jì)運(yùn)行時(shí)間
runBlocking {
val dispatcher = newFixedThreadPoolContext(4, "CoroutineThreadPoolDispatcher")
repeat(100) {
launch(dispatcher) {
delay(500)
println("coroutine println $it")
}
}
}
}.println()
}
驚不驚喜娄猫?意不意外?
同樣4個(gè)線程生闲,同樣100個(gè)任務(wù)媳溺,同樣每個(gè)任務(wù)耗時(shí)500毫秒,線程池運(yùn)行12秒碍讯,協(xié)程運(yùn)行0.5秒
What悬蔽?為什么會(huì)這樣?
原因就在于協(xié)程的優(yōu)勢
這里涉及到一個(gè)協(xié)程概念捉兴,非阻塞式掛起
這是什么意思呢蝎困?
就是當(dāng)協(xié)程任務(wù)掛起時(shí),不會(huì)阻塞協(xié)程的其他任務(wù)倍啥,也不會(huì)阻塞當(dāng)前線程的運(yùn)行禾乘,這就是非阻塞式掛起
栗子在上:過程分析
- 線程
提交了100個(gè)任務(wù),線程池同時(shí)執(zhí)行4個(gè)任務(wù)虽缕,每個(gè)任務(wù)都耗時(shí)500毫秒始藕;導(dǎo)致線程阻塞,原地等待彼宠,使得剩余的96個(gè)任務(wù)需要等待前面的任務(wù)完成才能繼續(xù)執(zhí)行(剩余任務(wù)同理)鳄虱;理論運(yùn)行時(shí)間計(jì)算 100 * 500 / 4 = 12500;即12秒左右
- 協(xié)程
提交了100個(gè)任務(wù)凭峡,線程池同時(shí)執(zhí)行4個(gè)任務(wù)拙已,每個(gè)任務(wù)都耗時(shí)500毫秒;
但是4菁健1蹲佟系宫!協(xié)程任務(wù)可以進(jìn)行非阻塞式掛起,這就導(dǎo)致了該任務(wù)沒有阻塞其他協(xié)程任務(wù)建车,也沒有阻塞線程扩借,線程依然可以繼續(xù)執(zhí)行其他協(xié)程任務(wù),這就影響了結(jié)果缤至,因?yàn)?00個(gè)任務(wù)幾乎是時(shí)同時(shí)在等待500毫秒潮罪;理論運(yùn)行時(shí)間計(jì)算 500 毫秒;即 0.5 秒左右
通過上面的例子&分析
協(xié)程對(duì)比于線程领斥,可以更優(yōu)的利用線程資源嫉到,從而達(dá)到更優(yōu)的體驗(yàn),更高的運(yùn)行速率
優(yōu)勢月洛?
方便何恶,高效,優(yōu)雅的異步
關(guān)于非阻塞式掛起
Kotlin協(xié)程的非阻塞式掛起是一種基于有限狀態(tài)自動(dòng)機(jī)來實(shí)現(xiàn)的一種技術(shù)嚼黔,有興趣的童鞋可以點(diǎn)擊鏈接進(jìn)行查看這是什么東東细层,這里不準(zhǔn)備詳談