Kotlin 协程超时

基本使用

package outtime

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

/**
 * 超时:动追踪一个相关 Job 的引用并启动了一个单独的协程
 * 在延迟后取消追踪,使用 withTimeout 函数来做这件事
 * 1、withTimeout 会抛出异常 TimeoutCancellationException <-extend--- CancellationException
 * 2、
 */
fun main() = runBlocking {

    withTimeout(1300L) {
        repeat(1000){
            i ->
            println("i==$i")
            delay(500L)
        }
    }

//    output:
//    i==0
//    i==1
//    i==2
//    Exception ===> in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1300 ms

}

超时取消 不报错TimeoutCancellationException

package outtime

import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeoutOrNull

/**
 * 使用withTimeoutOrNull 通过返回 null 来进行超时操作,从而替代抛出一个异常
 */
fun main() = runBlocking {

    val result = withTimeoutOrNull(1300L) {
        repeat(1000){
            i ->
            println("i==$i")
            delay(500L)
        }
        "Done"
    }

    println("Result is $result")
//    output:
//    i==0
//    i==1
//    i==2
//    Result is null

}

超时释放资源,线程安全,输出不一定是0

package outtime

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

var ab = 0

/**
 * absl withTimeout内初始化 输出的并不一定是0
 * 协程递增和递减获得的计数器是完全安全的,因为它总是发生在同一个主线程上
 */
class  abs{

    init {
        ab ++
    }

    fun close(){
        ab --
    }
}

/**
 *  withTimeout中的超时事件与在其块中运行的代码是异步的,
 * 并且可能随时发生,甚至在从timeout块内部返回之前。
 * 如果在块内打开或获取一些需要在块外关闭或释放的资源
 */
fun main() {

    runBlocking {
        repeat(100_000) {
            launch {
                val resource = withTimeout(60) { // Timeout of 60 ms
                    delay(50) // Delay for 50 ms
                    abs() // Acquire a resource and return it from withTimeout block
                }
                resource.close()
            }
        }
    }
    // Outside of runBlocking all coroutines have completed
    println(ab) // Print the number of resources still acqui


//    output:
//    0

    // 1021

}

解决释放资源不是0的问题–存储变量对象


```kotlin
package outtime

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

var abl = 0

/**
 * absl withTimeout外初始化
 * 在变量中存储对资源的引用
 * 输出的是0
 */
class absl {

    init {
        abl++
    }

    fun close() {
        abl--
    }
}

/**
 *  withTimeout中的超时事件与在其块中运行的代码是异步的,
 * 并且可能随时发生,甚至在从timeout块内部返回之前。
 * 如果在块内打开或获取一些需要在块外关闭或释放的资源
 */
fun main() {

    runBlocking {
        repeat(100_000) {
            launch {
                var resource: absl? = null
                withTimeout(60) { // Timeout of 60 ms
                    delay(50) // Delay for 50 ms
                    // Acquire a resource and return it from withTimeout block
                    resource = absl()
                }
                resource?.close()
            }
        }
    }
    // Outside of runBlocking all coroutines have completed
    println(ab) // Print the number of resources still acqui


//    output:
//    0

}

你可能感兴趣的:(Kotlin,android)