MST

星途 面试题库

面试题:Kotlin协程取消与超时之基础操作

在Kotlin协程中,如何使用`Job`来取消一个正在运行的协程?请举例说明,并解释取消后协程的状态变化。同时,如何设置协程的超时时间,使用哪种方法实现?
24.1万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试
  1. 使用Job取消正在运行的协程
    • 示例代码
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        repeat(1000) { i ->
            println("I'm sleeping $i...")
            delay(500)
        }
    }
    delay(1300)
    println("Canceling job...")
    job.cancel()
    job.join()
    println("Job is canceled")
}
  • 解释
    • 首先,通过launch启动一个协程,并将返回的Job对象赋值给job变量。
    • 协程内部使用repeat循环并通过delay模拟长时间运行的任务。
    • 外部通过delay(1300)等待1300毫秒后,调用job.cancel()方法取消协程。
    • job.join()用于等待协程真正取消完成,然后打印“Job is canceled”。
  1. 取消后协程的状态变化
    • 协程在被取消后,其状态会变为JobCanceling,然后快速转变为JobCancelled。当状态为JobCancelled时,协程已停止执行,并且任何等待该Job完成(如通过join方法)的操作都会立即返回。
  2. 设置协程的超时时间
    • 使用withTimeout方法
import kotlinx.coroutines.*

fun main() = runBlocking {
    try {
        withTimeout(1300) {
            repeat(1000) { i ->
                println("I'm sleeping $i...")
                delay(500)
            }
        }
    } catch (e: TimeoutCancellationException) {
        println("Operation timed out")
    }
}
  • 解释
    • withTimeout函数会在指定的时间(这里是1300毫秒)后取消协程。
    • 协程内部同样是repeat循环模拟长时间运行任务。
    • 如果在指定时间内协程没有完成,会抛出TimeoutCancellationException异常,在try - catch块中捕获该异常并处理。
  • 使用withTimeoutOrNull方法
import kotlinx.coroutines.*

fun main() = runBlocking {
    val result = withTimeoutOrNull(1300) {
        repeat(1000) { i ->
            println("I'm sleeping $i...")
            delay(500)
        }
        "Task completed"
    }
    if (result == null) {
        println("Operation timed out")
    } else {
        println("Result: $result")
    }
}
  • 解释
    • withTimeoutOrNullwithTimeout类似,但它不会抛出TimeoutCancellationException异常,而是在超时时返回null
    • 协程内部执行任务并返回一个结果。
    • 通过判断返回值是否为null来确定是否超时。如果为null,表示超时;否则,打印任务完成的结果。