Kotlin runBlocking、withContext、async用法

1. 範例程式碼

GitHub:

https://github.com/f40706/coroutine_scope_test

2. runBlocking用法

測試1

執行simulationBlocking、simulationBlocking2這兩個

/*
* 出現問題: Inappropriate blocking method call
* 原因這樣使用,雖然可以正常使用,但卻讓CoroutineScope失去了意義
* simulationBlocking搭配simulationBlocking2測試
* 再看simulationWithContext搭配simulationWithContext2的測試
* 他會堵塞CoroutineScope並失去暫停當前線程的功能
* 2022/03/20 05:05:24.686: A1
* 2022/03/20 05:05:25.692: A2 11
* 2022/03/20 05:05:25.694: B1
* 2022/03/20 05:05:26.696: B2 22
*/
simulationBlocking()
simulationBlocking2()
private fun simulationBlocking() {
    mJob = mCoroutineScopeSDK.coroutineScopeLaunch({
        val result = runBlocking(Dispatchers.IO) {
            showCurSystemTime("A1")
            delay(1000)
            11
        }
        showCurSystemTime("A2 $result")
    }, {

    })
}
private fun simulationBlocking2() {
    mJob = mCoroutineScopeSDK.coroutineScopeLaunch({
        val result = runBlocking(Dispatchers.IO) {
            showCurSystemTime("B1")
            delay(1000)
            22
        }
        showCurSystemTime("B2 $result")
    }, {
    })
}

測試2

執行simulationBlocking3

/**
 * runBlocking建議搭配async使用,因為async是併發,就算一條線被堵塞,也不會有什麼影響
 * withContext只是切換線程,把當前的暫停,但依然只有一條線在跑,並不是併發
 * 如果使用runBlocking將會把所有線程賭塞
 * 2022/03/20 05:31:10.833: B1
 * 2022/03/20 05:31:11.836: B2
 * 2022/03/20 05:31:12.840: result -> 77
 * */
simulationBlocking3()

private fun simulationBlocking3() {
mJob = mCoroutineScopeSDK.coroutineScopeLaunch({
val async = async(Dispatchers.IO) {
val result = runBlocking {
showCurSystemTime("B1")
delay(1000)
33
}
val result2 = runBlocking {
showCurSystemTime("B2")
delay(1000)
44
}
result + result2
}
showCurSystemTime("result -> ${async.await()}")
}, {
})
}

3. withContext用法

測試1

執行simulationWithContext、simulationWithContext2

/**
* 很明顯看到擁有Coroutine Scope暫停的功能
* 2022/03/20 05:05:40.129: B1
* 2022/03/20 05:05:40.129: A1
* 2022/03/20 05:05:41.131: A2 20
* 2022/03/20 05:05:41.133: B2 10
* */
simulationWithContext()
simulationWithContext2()
private fun simulationWithContext() {
mJob = mCoroutineScopeSDK.coroutineScopeLaunch({
val result = withContext(Dispatchers.IO) {
showCurSystemTime("A1")
delay(1000)
20
}
showCurSystemTime("A2 $result")
}, {

})
}

private fun simulationWithContext2() {
mJob = mCoroutineScopeSDK.coroutineScopeLaunch({
val result = withContext(Dispatchers.IO) {
showCurSystemTime("B1")
delay(1000)
10
}
showCurSystemTime("B2 $result")
}, {

})
}

4. async用法

測試1

執行simulationASYNC

/**
* 很明顯看出他是併發
* 但通常async會搭配await取得他返回值
* 可以同時有nasync在使用await
* 等待他們完成後,做處理
* 參考simulationASYNC2
* -----經過此處A-----
* -----經過此處B-----
* 2022/03/20 05:14:51.139: D1
* 2022/03/20 05:14:51.143: D2
* 2022/03/20 05:14:51.647: DD1
* 2022/03/20 05:14:51.649: DD2
* */
simulationASYNC()
private fun simulationASYNC() {
mJob = mCoroutineScopeSDK.coroutineScopeLaunch({
async {
showCurSystemTime("D1")
delay(500)
showCurSystemTime("DD1")
30
}
println("-----經過此處A----- ")
async {
showCurSystemTime("D2")
delay(500)
showCurSystemTime("DD2")
30
}
println("-----經過此處B----- ")
}, {

})
}

測試2

執行simulationASYNC2

/**
 * async屬於併發
 * async擁有await的功能
 * 等待async內部完成再繼續往下做
 * delay是暫停當前線程,因此其他線程依然可以繼續動作
 * 使用兩個async並將結果相加
 * 2022/03/20 05:06:00.061: C1
 * 2022/03/20 05:06:00.063: CC1
 * 2022/03/20 05:06:00.565: CCC1 -> 50
 * */
simulationASYNC2()
private fun simulationASYNC2() {
mJob = mCoroutineScopeSDK.coroutineScopeLaunch({
val async = async {
showCurSystemTime("C1")
delay(10)
20
}
val async2 = async {
showCurSystemTime("CC1")
delay(500)
30
}
showCurSystemTime("CCC1 -> ${async.await()+async2.await()}")
}, {

})
}

Kotlin

正在載入…

執行時發生錯誤。請重新整理頁面後再試一次。


訂閱Codeilin的旅程,若有最新消息會通知。

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

WordPress.com.

向上 ↑

%d 位部落客按了讚: