Kotlin 异步等待,并行性有限

Anu*_*iye 3 parallel-processing asynchronous async-await kotlin kotlin-coroutines

我正在使用 kotlin 测试一种行为,我想要进行与列表相对应的 api 调用。我正在使用 async wait 使其异步调用。这是一段模拟的代码:

/**
 * You can edit, run, and share this code. 
 * play.kotlinlang.org 
 */
import kotlinx.coroutines.*

fun main() {
    val numList = (1..20).toList()
    //print(numList)
    runBlocking(Dispatchers.IO.limitedParallelism(5)){
        numList.map{
          async{delayed(it)}
        }.awaitAll()
    }
}

suspend fun delayed(number: Int):Int {
    print("$number Start")
    delay(1000)
    println("$number end")
    return number
    
}
Run Code Online (Sandbox Code Playgroud)

我正在 1.6.0+ 版本上尝试

此打印的输出从 1 -20 开始,然后以 1-20 结束 我想控制这里的并行性,我不想一次性用所有请求轰炸服务器。我想要受控的异步性。

由于我的并行性有限,我期望得到像 1-5 开始、1-5 结束、5-10 开始、5-10 结束...15-20 开始、15-20 结束这样的响应

然而,这仍然是1-20的开始,1-20的结束。有限的并行性似乎控制着将使用的线程数量。我知道如何继续在这里实现控制吗?

bro*_*oot 5

你在这里限制了并行性,但你需要的是限制并发性。这两个词是相关的,但它们的意思不同。这里解释了差异:并发性和并行性之间有什么区别?

要限制并发性,您需要使用同步实用程序,在您的情况下最简单的是使用信号量:

val semaphore = Semaphore(5)
numList.map{
    async {
        semaphore.withPermit {
            delayed(it)
        }
    }
}.awaitAll()
Run Code Online (Sandbox Code Playgroud)

可以删除limitedParallelism(5),不需要。

或者,我们可以创建一个任务队列(Channel)并启动5协程来消耗其中的项目。它提供了对流程的更多控制,如果我们计划对大量任务(例如数万个)进行排队,那么保留任务队列可能比启动数千个协程对性能更好。但就您而言,信号量似乎是更好的方法,因为它更简单。