kotlin 协程 withTimeout 迷惑行为,有人知道为啥不?


#1

代码如下:

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout

var acquired = 0

class Resource {
    init {
        acquired++
    } // Acquire the resource

    fun close() {
        acquired--
    } // Release the resource
}


var repeatCount=0
var createRes = 0
var closeRes = 0
fun main() {
    runBlocking {
        repeat(20_000) {
            repeatCount+=1
            launch {
                val resource = withTimeout(60) { // Timeout of 60 ms
                    delay(50) // Delay for 50 ms
                    createRes += 1
                    Resource() // Acquire a resource and return it from withTimeout block
                }
                closeRes += 1
                resource.close() // Release the resource
            }
        }
    }

    println("repeatCount $repeatCount")
    println("createRes $createRes")
    println("closeRes $closeRes")
    println("acquired $acquired") // Print the number of resources still acquired
    println("close+acquire ${closeRes + acquired}")
}

上面这段代码的运行结果如下:
repeatCount 20000
createRes 17478
closeRes 16223
acquired 1255
close+acquire 17478

我的问题如下:
1、为什么repeat 2万次,但是 withTimeout 中的代码没有执行到2万次?
2、closeRes 的值为什么比 createRes 的值要少?如果是因为withTimeout 超时的话,那应该会抛出异常,可是程序正常执行完毕,并没有发生任何异常预格式化文本


#2

你怎么知道没抛异常,launch里加个try catch 然后把异常次数打印出来看看。

 try {
                    val resource = withTimeout(60) { // Timeout of 60 ms
                        delay(50) // Delay for 50 ms
                        createRes += 1
                        Resource() // Acquire a resource and return it from withTimeout block
                    }
                    closeRes += 1
                    resource.close() // Release the resource
                } catch (e: Exception) {
                    errorCount++
                }

#3

你设置的50ms这个点很神奇,抛出异常的时候,有的时候会执行println(A------)语句,有时候不会执行

fun main(){
    runBlocking {
        launch{
            try {
                withTimeout(60){
                    delay(50)
                    println("A----------")
                }
            }catch (e : Exception){
                e.printStackTrace()
            }
            println("B----------")
        }
    }
}
kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 60 ms
	at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:126)
	at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:92)
	at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run(EventLoop.common.kt:491)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:270)
	at kotlinx.coroutines.DefaultExecutor.run(DefaultExecutor.kt:68)
	at java.lang.Thread.run(Thread.java:745)
B----------

京ICP备16022265号-2 Kotlin China 2017 - 2018