MST

星途 面试题库

面试题:Kotlin协程的并发控制与异常处理

假设有多个Kotlin协程并发执行任务,这些任务可能会抛出异常。请阐述如何在协程中进行异常处理,确保即使部分协程出错,其他协程也能正常运行。同时说明如何使用`async`和`await`来实现并发任务并获取结果,举例说明如何处理`async`任务执行过程中的异常。
30.7万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试
  1. 协程异常处理以确保部分协程出错时其他协程正常运行
    • 使用try - catch:在每个协程内部,可以使用try - catch块来捕获异常。这样当一个协程内部发生异常时,该协程的异常不会传播到其他协程。例如:
import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        try {
            // 模拟可能抛出异常的任务
            throw RuntimeException("Task 1 failed")
        } catch (e: Exception) {
            println("Caught exception in task 1: $e")
        }
    }
    launch {
        delay(100)
        println("Task 2 is running fine")
    }
}
  • 使用CoroutineExceptionHandler:可以为CoroutineScope设置CoroutineExceptionHandler来全局捕获协程中的未处理异常。例如:
import kotlinx.coroutines.*

val exceptionHandler = CoroutineExceptionHandler { _, exception ->
    println("Caught exception: $exception")
}

fun main() = runBlocking {
    GlobalScope.launch(exceptionHandler) {
        throw RuntimeException("Task failed")
    }
    launch {
        delay(100)
        println("Another task is running fine")
    }
}
  1. 使用asyncawait实现并发任务并获取结果
    • async用于启动一个异步任务并返回一个Deferred对象,await用于等待Deferred对象完成并获取其结果。例如:
import kotlinx.coroutines.*

fun main() = runBlocking {
    val deferred1 = async {
        delay(1000)
        "Result of task 1"
    }
    val deferred2 = async {
        delay(2000)
        "Result of task 2"
    }
    val result1 = deferred1.await()
    val result2 = deferred2.await()
    println("$result1 and $result2")
}
  1. 处理async任务执行过程中的异常
    • 使用try - catch:可以在调用await的地方使用try - catch块来捕获async任务执行过程中抛出的异常。例如:
import kotlinx.coroutines.*

fun main() = runBlocking {
    val deferred = async {
        throw RuntimeException("Task failed")
    }
    try {
        val result = deferred.await()
        println(result)
    } catch (e: Exception) {
        println("Caught exception: $e")
    }
}
  • async内部使用try - catch:也可以在async块内部使用try - catch,然后返回一个合适的结果(比如null或者错误信息)。例如:
import kotlinx.coroutines.*

fun main() = runBlocking {
    val deferred = async {
        try {
            throw RuntimeException("Task failed")
            "Normal result"
        } catch (e: Exception) {
            "Error: $e"
        }
    }
    val result = deferred.await()
    println(result)
}