簡(jiǎn)單的理解Kotlin for Java的協(xié)程

記錄一下學(xué)習(xí)的知識(shí)

1.什么是協(xié)程?
  • 廣義的協(xié)程是一種在程序中處理并發(fā)任務(wù)的方案; 并且協(xié)程也是這種方案的一個(gè)組件
    例如:適配器模式是一種方案, 而項(xiàng)目中又存在具體的XxxAdapter,也是一個(gè)組件

  • 廣義的協(xié)程和線程屬于一個(gè)層級(jí)的概念,屬于并列的關(guān)系
    例如:如果需要異步處理任務(wù),你可以選擇線程,也可以選擇協(xié)程

2.什么是Kotlin for Java的協(xié)程?

Kotlin for Java的協(xié)程和廣義的協(xié)程并不相同.
Kotlin for Java的協(xié)程底層是基于線程,是一個(gè)線程框架,最終還是使用線程池來完成異步任務(wù)

3.Android中的協(xié)程代碼怎么寫?
  • 用launch來開啟一段協(xié)程
  • 把需要放在異步后臺(tái)工作的函數(shù),寫成suspend函數(shù),并且調(diào)用其他suspend函數(shù)來真正切換線程**
  • 最簡(jiǎn)單的使用GlobalScope.launch { ... }
GlobalScope.launch {
     showLog("Current Thread name: ${Thread.currentThread().name}")
}

打印結(jié)果: Current Thread name: DefaultDispatcher-worker-1, 這里可以看到不是主線程Main了

下面舉個(gè)例子說明: 比如有幾個(gè)函數(shù)

    fun ioCode1(){
        showLog("ioCode1 Thread name: ${Thread.currentThread().name}")
    }
    fun uiCode1(){
        showLog("uiCode1 Thread name: ${Thread.currentThread().name}")
    }
    fun ioCode2(){
        showLog("ioCode2 Thread name: ${Thread.currentThread().name}")
    }
    fun uiCode2(){
        showLog("uiCode2 Thread name: ${Thread.currentThread().name}")
    }
    fun ioCode3(){
        showLog("ioCode3 Thread name: ${Thread.currentThread().name}")
    }
    fun uiCode3(){
        showLog("uiCode3 Thread name: ${Thread.currentThread().name}")
    }

我們希望ioCode的函數(shù)在異步執(zhí)行,uiCode在主線程執(zhí)行,并且按指定的順序執(zhí)行1,2,3

如果不使用協(xié)程,我們可以這樣寫:

        thread {
            ioCode1()
            runOnUiThread {
                uiCode1()
                thread {
                    ioCode2()
                    runOnUiThread {
                        uiCode2()
                        thread {
                            ioCode3()
                            runOnUiThread {
                                uiCode3()
                            }
                        }
                    }
                }
            }
        }

從這個(gè)簡(jiǎn)單的例子可以看出,嵌套層次有點(diǎn)多,如果業(yè)務(wù)邏輯比較復(fù)雜,不利于后期維護(hù)和修改

使用Kotlin協(xié)程可以這樣寫:

首先需要改造一下ioCode1(),ioCode2(),ioCode3()異步函數(shù), 加上suspend標(biāo)識(shí)為掛起函數(shù), suspend并不會(huì)幫我們切換線程,需要加上withContext(Dispatchers.IO)來指定到IO線程

   GlobalScope.launch(Dispatchers.Main) {
        ioCode1()
        uiCode1()
        ioCode2()
        uiCode2()
        ioCode3()
        uiCode3()
    }

    suspend fun ioCode1() {
        withContext(Dispatchers.IO){
            showLog("ioCode1 Thread name: ${Thread.currentThread().name}")
        }
    }
    //同樣的寫法, 省略ioCode2() , ioCode3() 
    ...

打印結(jié)果:
D/ouwen: ioCode1 Thread name: DefaultDispatcher-worker-1
D/ouwen: uiCode1 Thread name: main
D/ouwen: ioCode2 Thread name: DefaultDispatcher-worker-3
D/ouwen: uiCode2 Thread name: main
D/ouwen: ioCode3 Thread name: DefaultDispatcher-worker-2
D/ouwen: uiCode3 Thread name: main

Dispatchers.Main : 把線程環(huán)境指定為Main主線程,當(dāng)掛起函數(shù)ioCode1()執(zhí)行完成后,會(huì)自動(dòng)切換回到Main主線程環(huán)境

GlobalScope.launch(Dispatchers.Main) {
    //運(yùn)行在 Main主線程環(huán)境
}
4.協(xié)程有什么優(yōu)勢(shì)?

a.性能的優(yōu)勢(shì)

這是相對(duì)而言的,例如:
Java: 當(dāng)有某個(gè)函數(shù)方法存在耗時(shí),但是調(diào)用的時(shí)候又不清楚這個(gè)函數(shù)耗時(shí),而放在主線程調(diào)用,就存在性能問題
Kotlin: 當(dāng)有某個(gè)函數(shù)方法存在耗時(shí),寫成suspend函數(shù),那么調(diào)用的時(shí)候,就必須開啟協(xié)程來調(diào)用,更好的避免性能問題

b.代碼簡(jiǎn)潔的優(yōu)勢(shì)
線性調(diào)用函數(shù),可以用看起來同步的代碼處理異步問題,不存在回調(diào)嵌套
線程可以自動(dòng)切回到原來的環(huán)境

5.suspend關(guān)鍵字是什么?

suspend關(guān)鍵作用: 標(biāo)識(shí)和提醒,提醒suspend函數(shù)必須在協(xié)程里面調(diào)用

如果一個(gè)函數(shù)有suspend關(guān)鍵字,那么該函數(shù)是掛起函數(shù),并且這個(gè)函數(shù)必須在另外一個(gè)掛起函數(shù)或者協(xié)程里面被調(diào)用,否則代碼就會(huì)提示報(bào)錯(cuò),無法通過編譯期

suspend不會(huì)切換線程 ,真正切換線程的操作是調(diào)用其他函數(shù)來實(shí)現(xiàn)
例如上面的: withContext(Dispatchers.IO)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末隘冲,一起剝皮案震驚了整個(gè)濱河市累魔,隨后出現(xiàn)的幾起案子慈参,更是在濱河造成了極大的恐慌,老刑警劉巖谆棺,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲤看,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)口注,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胜卤,“玉大人疆导,你說我怎么就攤上這事。” “怎么了澈段?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵悠菜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我败富,道長(zhǎng)悔醋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任兽叮,我火速辦了婚禮芬骄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鹦聪。我一直安慰自己账阻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布泽本。 她就那樣靜靜地躺著淘太,像睡著了一般。 火紅的嫁衣襯著肌膚如雪规丽。 梳的紋絲不亂的頭發(fā)上蒲牧,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音赌莺,去河邊找鬼冰抢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛艘狭,可吹牛的內(nèi)容都是我干的挎扰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缓升,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鼓鲁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起港谊,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎橙弱,沒想到半個(gè)月后歧寺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棘脐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年斜筐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛀缝。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡顷链,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出屈梁,到底是詐尸還是另有隱情嗤练,我是刑警寧澤榛了,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站煞抬,受9級(jí)特大地震影響霜大,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜革答,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一战坤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧残拐,春花似錦途茫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至眠菇,卻和暖如春边败,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捎废。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工笑窜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人登疗。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓排截,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親辐益。 傳聞我的和親對(duì)象是個(gè)殘疾皇子断傲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355