五個結(jié)論2022-12-24 有錯幫忙留言,一塊完善進(jìn)步
創(chuàng)新互聯(lián)建站基于成都重慶香港及美國等地區(qū)分布式IDC機(jī)房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)服務(wù)器托管報價,主機(jī)托管價格性價比高,為金融證券行業(yè)西部信息服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨(dú)享,G口帶寬及機(jī)柜租用的專業(yè)成都idc公司。
結(jié)論一. 協(xié)程是一個線程框架,協(xié)程依附于線程或者說在線程中執(zhí)行
結(jié)論二. 一個線程中可以啟動多個協(xié)程,啟動的協(xié)程不一定運(yùn)行在該線程
結(jié)論三. 一個線程中可以執(zhí)行多個協(xié)程,同一線程的不同協(xié)程按照啟動先后順序執(zhí)行代碼,依附不同線程的協(xié)程間執(zhí)行順序不固定(并發(fā))
結(jié)論四. 線程執(zhí)行到協(xié)程的掛起函數(shù)時,會暫停該協(xié)程的往下執(zhí)行,此時線程會去執(zhí)行該線程中的其他協(xié)程代碼,這個就是"非阻塞式"的含義
結(jié)論五. suspend關(guān)鍵字的含義是告訴線程,我這個函數(shù)的協(xié)程先暫停執(zhí)行,我要去其他線程執(zhí)行函數(shù)體代碼,你先執(zhí)行其他協(xié)程代碼,我稍后回來你再執(zhí)行我的協(xié)程
此時若指定suspend函數(shù)中代碼將要執(zhí)行線程仍為原線程,則原線程會"置之不理"函數(shù)及函數(shù)所在協(xié)程,協(xié)程會一直被掛起,不會再恢復(fù),
若是主線程的話會引起ANR
驗(yàn)證結(jié)論二與結(jié)論三
測試代碼class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程")
launch {log("協(xié)程B--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程") }
launch {log("協(xié)程C--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程") }
launch(Dispatchers.IO) {log("協(xié)程D--我是launch啟動的協(xié)程代碼,我運(yùn)行在IO線程") }
log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程")
}
}
}
執(zhí)行結(jié)果第一次執(zhí)行結(jié)果
ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程
ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程
ThreadHash[540585569] Thread[main,5,main] 協(xié)程B--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程
ThreadHash[540585569] Thread[main,5,main] 協(xié)程C--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程
ThreadHash[1632014539] Thread[DefaultDispatcher-worker-1,5,main] 協(xié)程D--我是launch啟動的協(xié)程代碼,我運(yùn)行在IO線程
第二次執(zhí)行結(jié)果
ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程
ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程
ThreadHash[1346142757] Thread[DefaultDispatcher-worker-1,5,main] 協(xié)程D--我是launch啟動的協(xié)程代碼,我運(yùn)行在IO線程
ThreadHash[540585569] Thread[main,5,main] 協(xié)程B--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程
ThreadHash[540585569] Thread[main,5,main] 協(xié)程C--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程
結(jié)果分析主線程中啟動了A,B,C,D四個協(xié)程,協(xié)程D運(yùn)行在IO線程
主線程中執(zhí)行A,B,C三個協(xié)程時,按照A,B,C的啟動順序執(zhí)行,協(xié)程D則跟其他3個協(xié)程并發(fā)執(zhí)行
由此得出結(jié)論二與結(jié)論三
驗(yàn)證結(jié)論四
測試代碼class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程")
launch {log("協(xié)程B--主線程,開始計(jì)算")
var count = 0
repeat(1000000000) {if (it == 500000000) {log("協(xié)程B--主線程,遇到了協(xié)程B中掛起函數(shù)delay,暫停該協(xié)程執(zhí)行其他協(xié)程")
delay(500)
log("協(xié)程B--主線程,協(xié)程delay結(jié)束,該協(xié)程繼續(xù)執(zhí)行")
}
count++
}
count.also {log("協(xié)程B--主線程,結(jié)束計(jì)算")
}
}
launch {log("協(xié)程C--主線程,開始計(jì)算")
var count = 0
repeat(1000000000) {if (it == 500000000) {log("協(xié)程C--主線程,遇到了協(xié)程C中掛起函數(shù)delay,暫停該協(xié)程執(zhí)行其他協(xié)程")
delay(500)
log("協(xié)程C--主線程,協(xié)程delay結(jié)束,該協(xié)程繼續(xù)執(zhí)行")
}
count++
}
count.also {log("協(xié)程C--主線程,結(jié)束計(jì)算")
}
}
log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程")
}
}
}
執(zhí)行結(jié)果16:47:30.516 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程
16:47:30.524 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程
16:47:30.525 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程B--主線程,開始計(jì)算
16:47:36.949 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程B--主線程,遇到了協(xié)程B中掛起函數(shù)delay,暫停該協(xié)程執(zhí)行其他協(xié)程
16:47:36.958 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程C--主線程,開始計(jì)算
16:47:43.384 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程C--主線程,遇到了協(xié)程C中掛起函數(shù)delay,暫停該協(xié)程執(zhí)行其他協(xié)程
16:47:43.385 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程B--主線程,協(xié)程delay結(jié)束,該協(xié)程繼續(xù)執(zhí)行
16:47:49.807 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程B--主線程,結(jié)束計(jì)算
16:47:49.808 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程C--主線程,協(xié)程delay結(jié)束,該協(xié)程繼續(xù)執(zhí)行
16:47:56.229 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程C--主線程,結(jié)束計(jì)算
結(jié)果分析A,B,C三個協(xié)程都是主線程協(xié)程,先打印了協(xié)程A的日志,然后執(zhí)行協(xié)程B,執(zhí)行過程中遇到掛起函數(shù),協(xié)程B被掛起暫停,
此時線程開始執(zhí)行協(xié)程C中代碼,執(zhí)行過程中再遇掛起函數(shù),此時協(xié)程B的delay早已經(jīng)超時,線程繼續(xù)執(zhí)行協(xié)程B代碼,
協(xié)程B執(zhí)行完后繼續(xù)執(zhí)行協(xié)程C剩余代碼
由此得出結(jié)論四
驗(yàn)證結(jié)論五
測試代碼用例一:
class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程")
withContext(Dispatchers.IO) {log("我是被掛起函數(shù)withContext指定在IO線程進(jìn)行的任務(wù),掛起暫停協(xié)程A開始")
var count = 0
repeat(1000000000) {count++
}
log("我是被掛起函數(shù)withContext指定在IO線程進(jìn)行的任務(wù),掛起暫停協(xié)程A結(jié)束")
}
launch {log("協(xié)程B--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程") }
launch {log("協(xié)程C--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程") }
log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程")
}
}
}
用例二:
class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程")
withContext(Dispatchers.Main) {log("我是被掛起函數(shù)withContext指定在Main線程進(jìn)行的任務(wù),掛起暫停協(xié)程A開始")
var count = 0
repeat(1000000000) {count++
}
log("我是被掛起函數(shù)withContext指定在Main線程進(jìn)行的任務(wù),掛起暫停協(xié)程A結(jié)束")
}
launch {log("協(xié)程B--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程") }
launch {log("協(xié)程C--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程") }
log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程")
}
}
}
執(zhí)行結(jié)果用例一執(zhí)行結(jié)果
17:07:20.334 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程
17:07:20.370 System.out: ThreadHash[144796025] Thread[DefaultDispatcher-worker-1,5,main] 我是被掛起函數(shù)withContext指定在IO線程進(jìn)行的任務(wù),掛起暫停協(xié)程A開始
17:07:25.683 System.out: ThreadHash[144796025] Thread[DefaultDispatcher-worker-1,5,main] 我是被掛起函數(shù)withContext指定在IO線程進(jìn)行的任務(wù),掛起暫停協(xié)程A結(jié)束
17:07:25.687 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運(yùn)行在主線程
17:07:25.689 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程B--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程
17:07:25.690 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程C--我是launch啟動的協(xié)程代碼,我運(yùn)行在主線程
用例二執(zhí)行結(jié)果只有下面一行
17:12:45.177 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運(yùn)行在主線程
結(jié)果分析用例一中用withContext掛起函數(shù),指定'函數(shù)中代碼將要執(zhí)行線程IO線程' 協(xié)程A正常被掛起,然后恢復(fù)執(zhí)行,然后執(zhí)行協(xié)程B協(xié)程C
用例二中用withContext掛起函數(shù),指定'函數(shù)中代碼將要執(zhí)行線程仍為原線程(主線程)',主線程對函數(shù)及函數(shù)所在協(xié)程 "置之不理"
,協(xié)程會一直被掛起,不會再恢復(fù),代碼就卡這里了,多點(diǎn)幾下應(yīng)用就ANR了
由此得出結(jié)論五
參考文獻(xiàn)kotlin官網(wǎng)翻譯 https://www.kotlincn.net/docs/reference/coroutines/basics.html
谷歌官網(wǎng) https://developer.android.google.cn/kotlin/coroutines/coroutines-best-practices
Kotlin協(xié)程在Android中的掛起流程 https://maimai.cn/article/detail?fid=1638818450&efid=Bb3L1WdcCTmFgqVubzu92w
Benny Huo https://www.bennyhuo.com/book/kotlin-coroutines/01-intro.html#%E5%85%B3%E4%BA%8E%E4%BD%9C%E8%80%85
可能是最全的Kotlin協(xié)程講解 https://blog.csdn.net/zou8944/article/details/106447727?share_token=b127e799-a6a7-4e2a-9073-6ce2a286e151
一文快速入門 Kotlin 協(xié)程 https://juejin.cn/post/6908271959381901325
KOTLIN中的協(xié)程,用起來原來這么簡單? https://www.freesion.com/article/2493883525/
Kotlin: Suspend掛起 https://blog.csdn.net/qq_39969226/article/details/101058033
【碼上開學(xué)】Kotlin 協(xié)程的掛起好神奇好難懂?今天我把它的皮給扒了 http://www.javashuo.com/article/p-uopxaafq-dd.html
Kotlin協(xié)程深入了解一波 http://192.168.120.239:4999/web/#/6/685
Kotlin-協(xié)程(4)-啟動&分析執(zhí)行過程 https://juejin.cn/post/6844903822834270215
Kotlin 協(xié)程一 —— 協(xié)程 Coroutine SharpCJ's blog https://www.cnblogs.com/joy99/p/15805916.html
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧