協程入門(四):啓動模式

啓動模式

模式 描述
缺省 默認爲DEFAULT
DEFAULT 當即等待被調度執行()
ATOMIC 當即等待被調度執行,而且開始執行前沒法被取消,直到執行完畢或者遇到第一個掛起點suspend
UNDISPATCHED 當即在當前線程執行協程體內容
LAZY 須要手動觸發纔會進入等待調度

示例

缺省

協程採用缺省的啓動器, 當父協程執行完1,3後就會調度子協程執行2bash

/**
     * 啓動模式, 缺省時
     *
     * 協程當即等待被調度執行(等待被調度,不是當即執行)
     *
     * 打印:
     * 1
     * 3
     * 2
     */
    @Test
    fun coroutineStart() = runBlocking {
        println("1")
        launch {
            println("2")
        }
        println("3")
        delay(3000)
    }
複製代碼
DEFAULT
/**
     * DEFAULT啓動模式,效果同缺省時一致
     */
    @Test
    fun default() = runBlocking {
        println("1")
        launch( start = CoroutineStart.DEFAULT) {
            println("2")
        }
        println("3")
        delay(3000)
    }
複製代碼
UNDISPATCHED

UNDISPATCHED的協程會當即執行,因此1後先執行2完畢後才能執行到3微信

/**
     * UNDISPATCHED啓動模式,當即運行該協程體內容(相比其它啓動方式少了等待過程)
     *
     * 打印:
     * 1
     * 2
     * 3
     */
    @Test
    fun unDispatched() = runBlocking {
        println("1")
        launch(start = CoroutineStart.UNDISPATCHED) {
            //2優先於3執行
            println("2")
        }
        println("3")
    }
複製代碼
LAZY

lazy如字面意思,懶惰,須要咱們主動觸發才能進入等待調度階段,不然不會有機會執行到。atom

  • 調用 Job.start,主動觸發協程的調度執行
  • 調用 Job.join,隱式的觸發協程的調度執行
/**
     * lazy啓動方式,須要主動觸發才能進入等待調度階段
     *
     * - 調用 Job.start,主動觸發協程的調度執行
     * - 調用 Job.join,隱式的觸發協程的調度執行
     *
     * 使用start觸發打印出:
     * 1
     * 3
     * 2
     * 使用join觸發打印出:
     * 1
     * 2
     * 3
     * 若是下述例子去掉job.start(),則確定是:
     * 1
     * 3
     */
    @Test
    fun lazy() = runBlocking {
        println("1")
        val job = launch(start = CoroutineStart.LAZY) {
            //2優先於3執行
            println("2")
        }

        //lazy須要手動觸發,讓其協程進入等待調度階段
        job.start()
        //join會堵塞當前協程等待job協程執行完畢
        //job.join()
        println("3")
    }

    /**
     * 注意一旦lazy協程體沒有經過start執行完畢或者經過cancel取消掉,則runBlocking永遠不會退出。
     * runBlocking會等到裏面所有協程結束才退出
     *
     * 打印出:
     * 1
     * 3
     * 4
     */
    @Test
    fun lazy2() = runBlocking {
        println("1")
        val job = launch(start = CoroutineStart.LAZY) {
            println("2")
        }
        println("3")
        //job.start()
        //job.cancel()
        delay(3000)
        println("4")
    }
複製代碼
ATOMIC

ATOMIC啓動模式,與DEFAULT相似,當即等待被調度執行spa

區別在於: ATOMIC開始執行前沒法被取消,直到執行完畢或者遇到第一個掛起點, DEFAULT執行前能夠被取消。線程

/**
     * ATOMIC啓動模式,當即等待被調度執行,而且開始執行前沒法被取消,直到執行完畢或者遇到第一個掛起點。
     *
     * 該示例能夠看出在一樣通過cancel操做後,atomic協程依舊會被啓動,而其它則不會啓動了
     * 打印出:
     * 1
     * 3
     * atomic run
     */
    @Test
    fun atomic() = runBlocking {
        println("1")
        val job = launch(start = CoroutineStart.ATOMIC) {
            println("atomic run")
        }
        job.cancel()
        println("3")
    }

    /**
     *
     * 該示例演示atomic被cancel後遇到第一個掛起點取消運行的效果
     *
     * 打印出:
     *
     * 1
     * 2
     * atomic run
     * 3
     */
    @Test
    fun atomic2() = runBlocking {
        println("1")
        val job = launch(start = CoroutineStart.ATOMIC) {
            println("atomic run")
            //遇到了掛起點,cancel生效,不會再執行打印atomic end
            delay(3000)
            println("atomic end")
        }
        job.cancel()
        println("2")
        delay(5000)
        println("3")
    }

    /**
     * 該例子能夠看出,在未運行前,default,lazy能夠被cancel取消,
     * unDidpatcher由於會當即在當前線程執行,因此該例子中的cancel自己沒啥意義了
     *
     * 輸出:
     * 1
     * unDispatcherJob run
     * 2
     * atomic run
     */
    @Test
    fun atomic3() = runBlocking {
        println("1")
        val job = launch(start = CoroutineStart.ATOMIC) {
            println("atomic run")
        }
        job.cancel()

        val defaultJob = launch(start = CoroutineStart.DEFAULT) {
            println("default run")
        }
        defaultJob.cancel()

        val lazyJob = launch(start = CoroutineStart.LAZY) {
            println("lazyJob run")
        }
        lazyJob.start()
        lazyJob.cancel()

        val unDispatcherJob = launch(start = CoroutineStart.UNDISPATCHED) {
            println("unDispatcherJob run")
        }
        unDispatcherJob.cancel()

        println("2")
    }
複製代碼

微信公衆號

相關文章
相關標籤/搜索