MST

星途 面试题库

面试题:Kotlin协程的并发策略在网络请求中的应用

假设一个应用场景,需要同时发起多个网络请求,但又要控制并发数量以避免耗尽系统资源。请阐述如何利用Kotlin协程的并发策略(如使用`Dispatchers`、`CoroutineScope`、`Semaphore`等)来实现这一需求,并给出完整的代码示例和对各部分代码功能的解释。
14.4万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. Dispatchers:用于指定协程运行的线程上下文,例如 Dispatchers.IO 适用于I/O密集型任务,Dispatchers.Default 适用于CPU密集型任务。
  2. CoroutineScope:定义协程的作用域,控制协程的生命周期。
  3. Semaphore:用于限制并发数量,它类似于一个计数器,每次获取信号量时计数器减一,释放信号量时计数器加一。

代码示例

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Semaphore

// 定义最大并发数
private const val MAX_CONCURRENT_REQUESTS = 3

fun main() = runBlocking {
    // 创建一个信号量,初始值为最大并发数
    val semaphore = Semaphore(MAX_CONCURRENT_REQUESTS)
    // 创建一个协程作用域
    val coroutineScope = CoroutineScope(Job() + Dispatchers.Default)

    // 模拟多个网络请求
    val requests = (1..10).map { requestNumber ->
        coroutineScope.async {
            // 获取信号量,若信号量不足则等待
            semaphore.acquire()
            try {
                // 模拟网络请求
                delay((1000 * (1..3).random()).toLong())
                println("Request $requestNumber completed")
            } finally {
                // 释放信号量
                semaphore.release()
            }
        }
    }

    // 等待所有请求完成
    requests.forEach { it.await() }

    // 取消协程作用域
    coroutineScope.cancel()
}

代码功能解释

  1. MAX_CONCURRENT_REQUESTS:定义了允许同时执行的最大网络请求数量。
  2. Semaphore(MAX_CONCURRENT_REQUESTS):创建一个信号量实例,初始值为 MAX_CONCURRENT_REQUESTS,表示最多允许 MAX_CONCURRENT_REQUESTS 个协程同时执行。
  3. CoroutineScope(Job() + Dispatchers.Default):创建一个协程作用域,使用 Dispatchers.Default 作为线程上下文,Job 用于管理协程的生命周期。
  4. semaphore.acquire():获取信号量,如果当前信号量的值为0(即所有允许的并发任务都在执行中),则当前协程会被挂起,直到有信号量可用。
  5. semaphore.release():释放信号量,使信号量的值加一,允许其他等待的协程获取信号量并继续执行。
  6. delay((1000 * (1..3).random()).toLong()):模拟网络请求的延迟,每次延迟时间在1秒到3秒之间随机。
  7. requests.forEach { it.await() }:等待所有异步任务完成。
  8. coroutineScope.cancel():取消协程作用域,确保所有协程在程序结束时正确清理。