首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >限制可在作用域中运行的协程的最大数量

限制可在作用域中运行的协程的最大数量
EN

Stack Overflow用户
提问于 2019-10-17 16:52:06
回答 4查看 3.1K关注 0票数 6

我在将当前的应用程序从Java转换为Kotlin时遇到了这个问题。

用于使用线程从服务器传输数据的java实现。

它将创建大约100个不同的线程来请求数据,但从我看到的情况来看,一次运行的线程不超过4个,其他线程将等待线程完成后再启动。

在将其翻译为Kotlin时,我使用了协程

这就产生了一个问题,因为服务器显然无法处理实际发送的100个请求。

所有协程都在相同的作用域中启动,所以是这样的:

代码语言:javascript
复制
//this is a custom scope that launches on Dispatchers.IO + a job that I can use to cancel everything
transferScope.launch {
     //loadData is a suspending function that returns true/false 
     val futures = mDownloadJobs.map{ async { it.loadData() } }
     val responses = futures.awaitAll()
     //check that everything in responses is true etc....
}

有没有一种方法可以让特定的transferScope一次只允许5个协程,然后当一个协程结束时,让另一个不同的协程运行?(我不关心顺序)

如果不能通过作用域做到这一点,有没有其他方法可以实现这一点?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-10-17 18:04:16

在提出请求之前,要求每个协程程序从总共5个许可证中获得Kotlin Semaphore许可证。

如下所示:

代码语言:javascript
复制
    import kotlinx.coroutines.sync.Semaphore

    val requestSemaphore = Semaphore(5)

    val futures = mDownloadJobs.map {
        async {
            // Will limit number of concurrent requests to 5
            requestSemaphore.withPermit {
                it.loadData()
            }
        }
    }

    val responses = futures.awaitAll()
票数 21
EN

Stack Overflow用户

发布于 2020-01-24 05:49:34

我相信你应该引导和限制你正在创建的协程的创建。

代码语言:javascript
复制
val channel = Channel<Job>()

transferScope.launch {
  mDownloadJobs.forEach { channel.send(it) }
  channel.close() // don't forget to close the channel
}

coroutineScope {
    val responses = mutableListOf<Any>()
    repeat(5).map { 
      launch {
        for (job in mDownloadJobsChannel) {
          responses.add(jobs.loadData())
        }
      }
    }
}

这种情况下的并行化是5个协程。

我没有测试这段代码:D,我相信有更干净的方法可以做到这一点。

票数 2
EN

Stack Overflow用户

发布于 2019-10-17 17:13:25

您可以这样做,将请求分组为4个块,启动协程来处理它们,并等待该组完成后再启动新的请求。

代码语言:javascript
复制
requests.chunked(4).forEachIndexed { index, chunk ->
    coroutineScope {
        LOG("processing chunk $index")
        chunk.forEach {
            launch {
                delay(100)
            }
        }
        LOG("done processing $index")
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58428584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档