Kotlin協(xié)程代碼執(zhí)行順序-創(chuàng)新互聯(lián)

2022-12-24 有錯幫忙留言,一塊完善進步

創(chuàng)新互聯(lián)建站基于成都重慶香港及美國等地區(qū)分布式IDC機房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)服務(wù)器托管報價,主機托管價格性價比高,為金融證券行業(yè)西部信息服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨享,G口帶寬及機柜租用的專業(yè)成都idc公司。
五個結(jié)論
結(jié)論一. 協(xié)程是一個線程框架,協(xié)程依附于線程或者說在線程中執(zhí)行
結(jié)論二. 一個線程中可以啟動多個協(xié)程,啟動的協(xié)程不一定運行在該線程
結(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
驗證結(jié)論二與結(jié)論三 測試代碼
class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程")
            launch {log("協(xié)程B--我是launch啟動的協(xié)程代碼,我運行在主線程") }
            launch {log("協(xié)程C--我是launch啟動的協(xié)程代碼,我運行在主線程") }
            launch(Dispatchers.IO) {log("協(xié)程D--我是launch啟動的協(xié)程代碼,我運行在IO線程") }
            log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程")
        }
    }
}
執(zhí)行結(jié)果
第一次執(zhí)行結(jié)果
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程B--我是launch啟動的協(xié)程代碼,我運行在主線程
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程C--我是launch啟動的協(xié)程代碼,我運行在主線程
    ThreadHash[1632014539] Thread[DefaultDispatcher-worker-1,5,main] 協(xié)程D--我是launch啟動的協(xié)程代碼,我運行在IO線程
第二次執(zhí)行結(jié)果
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程
    ThreadHash[1346142757] Thread[DefaultDispatcher-worker-1,5,main] 協(xié)程D--我是launch啟動的協(xié)程代碼,我運行在IO線程
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程B--我是launch啟動的協(xié)程代碼,我運行在主線程
    ThreadHash[540585569] Thread[main,5,main] 協(xié)程C--我是launch啟動的協(xié)程代碼,我運行在主線程
結(jié)果分析
主線程中啟動了A,B,C,D四個協(xié)程,協(xié)程D運行在IO線程
    主線程中執(zhí)行A,B,C三個協(xié)程時,按照A,B,C的啟動順序執(zhí)行,協(xié)程D則跟其他3個協(xié)程并發(fā)執(zhí)行

    由此得出結(jié)論二與結(jié)論三
驗證結(jié)論四 測試代碼
class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程")
            launch {log("協(xié)程B--主線程,開始計算")
                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é)束計算")
                }
            }
            launch {log("協(xié)程C--主線程,開始計算")
                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é)束計算")
                }
            }
            log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程")
        }
    }
}
執(zhí)行結(jié)果
16:47:30.516 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程
16:47:30.524 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程
16:47:30.525 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程B--主線程,開始計算
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--主線程,開始計算
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é)束計算
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é)束計算
結(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é)論四
驗證結(jié)論五 測試代碼
用例一:
class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程")
            withContext(Dispatchers.IO) {log("我是被掛起函數(shù)withContext指定在IO線程進行的任務(wù),掛起暫停協(xié)程A開始")
                var count = 0
                repeat(1000000000) {count++
                }
                log("我是被掛起函數(shù)withContext指定在IO線程進行的任務(wù),掛起暫停協(xié)程A結(jié)束")
            }
            launch {log("協(xié)程B--我是launch啟動的協(xié)程代碼,我運行在主線程") }
            launch {log("協(xié)程C--我是launch啟動的協(xié)程代碼,我運行在主線程") }
            log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程")
        }
    }
}
用例二:
class TestActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        runBlocking {log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程")
            withContext(Dispatchers.Main) {log("我是被掛起函數(shù)withContext指定在Main線程進行的任務(wù),掛起暫停協(xié)程A開始")
                var count = 0
                repeat(1000000000) {count++
                }
                log("我是被掛起函數(shù)withContext指定在Main線程進行的任務(wù),掛起暫停協(xié)程A結(jié)束")
            }
            launch {log("協(xié)程B--我是launch啟動的協(xié)程代碼,我運行在主線程") }
            launch {log("協(xié)程C--我是launch啟動的協(xié)程代碼,我運行在主線程") }
            log("協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程")
        }
    }
}
執(zhí)行結(jié)果
用例一執(zhí)行結(jié)果
17:07:20.334 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程
17:07:20.370 System.out: ThreadHash[144796025] Thread[DefaultDispatcher-worker-1,5,main] 我是被掛起函數(shù)withContext指定在IO線程進行的任務(wù),掛起暫停協(xié)程A開始
17:07:25.683 System.out: ThreadHash[144796025] Thread[DefaultDispatcher-worker-1,5,main] 我是被掛起函數(shù)withContext指定在IO線程進行的任務(wù),掛起暫停協(xié)程A結(jié)束
17:07:25.687 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我也運行在主線程
17:07:25.689 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程B--我是launch啟動的協(xié)程代碼,我運行在主線程
17:07:25.690 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程C--我是launch啟動的協(xié)程代碼,我運行在主線程

用例二執(zhí)行結(jié)果只有下面一行
17:12:45.177 System.out: ThreadHash[107566656] Thread[main,5,main] 協(xié)程A--我是runBlocking啟動的協(xié)程代碼,我運行在主線程
結(jié)果分析
用例一中用withContext掛起函數(shù),指定'函數(shù)中代碼將要執(zhí)行線程IO線程' 協(xié)程A正常被掛起,然后恢復(fù)執(zhí)行,然后執(zhí)行協(xié)程B協(xié)程C
用例二中用withContext掛起函數(shù),指定'函數(shù)中代碼將要執(zhí)行線程仍為原線程(主線程)',主線程對函數(shù)及函數(shù)所在協(xié)程 "置之不理"
,協(xié)程會一直被掛起,不會再恢復(fù),代碼就卡這里了,多點幾下應(yīng)用就ANR了

由此得出結(jié)論五
參考文獻
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海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

分享題目:Kotlin協(xié)程代碼執(zhí)行順序-創(chuàng)新互聯(lián)
分享URL:http://bm7419.com/article6/gecog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、外貿(mào)建站、營銷型網(wǎng)站建設(shè)、全網(wǎng)營銷推廣、網(wǎng)站內(nèi)鏈、做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)