4.協(xié)程的異常處理(2)

異常的傳播
異常傳播是指異常在父子協(xié)程中的傳播蝴悉,什么是父子協(xié)程彰阴,在當前協(xié)程中又啟動一個協(xié)程,那么這個新啟動的協(xié)程就是當前協(xié)程的子協(xié)程拍冠。異常的傳播涉及到協(xié)程作用域的概念
一協(xié)程作用域

1.協(xié)程作用域本身是一個接口

public interface CoroutineScope {
    //此作用域的上下文
    //上下文由作用域封裝尿这,用于實現協(xié)程生成器,這些生成器是作用域上的擴展
    //此屬性除了為了高級用途而訪問[Job]實例外庆杜,不推薦訪問
    //通常應該包含一個Job的實例來執(zhí)行結構化并發(fā)
    public val coroutineContext: CoroutineContext
}

子類如下


clipboard.png

看一個例子射众,來加深理解作用域的父子關系

GlobalScope.launch {
    println("GlobalScope ${this}")
    launch {
        println("A ${this}")
        launch {
            println("A1 ${this}")
        }
    }

    launch {
        println("B ${this}")
    }
}.join()

打印

GlobalScope StandaloneCoroutine{Active}@4957b7c3
A StandaloneCoroutine{Active}@507cdd7a
B StandaloneCoroutine{Active}@64a45f82
A1 StandaloneCoroutine{Active}@544353ad

關系如下圖所示


4232467852.png

作用域啟動新協(xié)程也是一個新的作用域,它們的關系可以并列晃财,也可以包含叨橱,組成了一個作用域的樹形結構默認情況下,每個協(xié)程都要等待它的子協(xié)程全部完成后拓劝,才能結束自己雏逾。這種形式,就被稱為結構化的并發(fā)

2.我們之前啟動協(xié)程一直用的是GlobalScope郑临,GlobalScope是一個頂級的協(xié)程作用域栖博,此外還有coroutineScope{...}以及 supervisorScope{...}等,這里我們重點講一下跟異常傳播有關系的coroutineScope{...}跟supervisorScope{...}
coroutineScope源碼

//創(chuàng)建協(xié)程作用域并在此范圍調用指定的代碼塊
//該作用域繼承了外部作用域的協(xié)程上下文但是重寫了里面的Job
//這個函數是為分解并行工作而設計的
//當這個作用域內的任何子協(xié)同程序失敗時厢洞,所有其余的子協(xié)程都被取消
public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R =
    suspendCoroutineUninterceptedOrReturn { uCont ->
        val coroutine = ScopeCoroutine(uCont.context, uCont)
        coroutine.startUndispatchedOrReturn(coroutine, block)
    }

來看一下異常傳播對于coroutineScope{...}中是怎樣的

coroutineScope {
    launch {
        log(1)
        launch {
            log(2)
            throw ArithmeticException()
        }
    }
    launch {
        delay(200)
        log(3)
    }
}

打印如下

18:19:32:955 [DefaultDispatcher-worker-1] 1
18:19:32:955 [DefaultDispatcher-worker-2] 2
Exception in thread "main" java.lang.ArithmeticException

coroutineScope 當中協(xié)程異常會觸發(fā)父協(xié)程的取消仇让,進而將整個協(xié)程作用域取消掉,如果對 coroutineScope 整體進行捕獲躺翻,也可以捕獲到該異常

supervisorScope源碼

//創(chuàng)建協(xié)程作用域并在此作用域調用指定的代碼塊
//該作用域繼承了外部作用域的協(xié)程上下文但是重寫了里面的Job
//子協(xié)程的失敗不會導致此作用域失敗丧叽,也不會影響其他子協(xié)程
public suspend fun <R>  supervisorScope(block: suspend CoroutineScope.() -> R): R =
    suspendCoroutineUninterceptedOrReturn { uCont ->
        val coroutine = SupervisorCoroutine(uCont.context, uCont)
        coroutine.startUndispatchedOrReturn(coroutine, block)
}

來看一下異常傳播在supervisorScope中是怎樣的

supervisorScope{
    launch {
        log(1)
        throw ArithmeticException()
    }
    launch {
        delay(200)
        log(2)
    }
}

打印如下

18:33:15:486 [DefaultDispatcher-worker-1] 1
18:33:15:523 [DefaultDispatcher-worker-1] 2
Exception in thread "DefaultDispatcher-worker-1" java.lang.ArithmeticException

如何捕獲異常如下

val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
    log(throwable)
}
supervisorScope{
    launch (exceptionHandler){
        log(1)
        throw ArithmeticException()
    }
    launch {
        delay(200)
        log(2)
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市公你,隨后出現的幾起案子踊淳,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迂尝,死亡現場離奇詭異脱茉,居然都是意外死亡,警方通過查閱死者的電腦和手機垄开,發(fā)現死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門琴许,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人溉躲,你說我怎么就攤上這事榜田。” “怎么了锻梳?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵箭券,是天一觀的道長。 經常有香客問我唱蒸,道長邦鲫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任神汹,我火速辦了婚禮庆捺,結果婚禮上,老公的妹妹穿的比我還像新娘屁魏。我一直安慰自己滔以,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布氓拼。 她就那樣靜靜地躺著你画,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桃漾。 梳的紋絲不亂的頭發(fā)上坏匪,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音撬统,去河邊找鬼适滓。 笑死,一個胖子當著我的面吹牛恋追,可吹牛的內容都是我干的凭迹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼苦囱,長吁一口氣:“原來是場噩夢啊……” “哼嗅绸!你這毒婦竟也來了?” 一聲冷哼從身側響起撕彤,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤鱼鸠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體蚀狰,經...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡漆弄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了造锅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡廉邑,死狀恐怖哥蔚,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蛛蒙,我是刑警寧澤糙箍,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站牵祟,受9級特大地震影響深夯,放射性物質發(fā)生泄漏。R本人自食惡果不足惜诺苹,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一咕晋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧收奔,春花似錦掌呜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至翩肌,卻和暖如春模暗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背念祭。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工兑宇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棒卷。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓顾孽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親比规。 傳聞我的和親對象是個殘疾皇子若厚,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345