【问题标题】:Kotlin coroutines running sequentially even with keyword async即使使用关键字 async,Kotlin 协程也会按顺序运行
【发布时间】:2021-12-23 03:21:29
【问题描述】:

大家好,我正在尝试提高我系统中某些计算的性能。基本上我想根据一些数据生成一系列动作。这不能很好地扩展,我想尝试并行执行此操作并在之后获得结果(有点像期货的工作方式)

我有一个包含一系列实现的接口,这些实现可以获取一组操作。并希望并行调用所有这些并等待最后的结果。

问题是,当我查看日志时,它清楚地按顺序执行此操作,并在进入下一个之前等待每个动作吸气剂。我以为 async 会异步执行此操作,但事实并非如此。

runBlocking 所在的方法是在 spring 事务中。也许这与它有关。

runBlocking {
       val actions = actionsReportGetters.map { actionReportGetter ->
           async {
             getActions(actionReportGetter, abstractUser)
           }
       }.awaitAll().flatten()

       allActions.addAll(actions)
}
private suspend fun getActions(actionReportGetter: ActionReportGetter, traderUser: TraderUser): List<Action> {
        return actionReportGetter.getActions(traderUser)
}
interface ActionReportGetter {

    fun getActions(traderUser: TraderUser): List<Action>
}

【问题讨论】:

  • 你得到什么日志?代码对我来说看起来不错。所有异步块将并行运行。见this
  • @ArpitShukla 当我从 ActionReportGetter 的实现中删除代码并将其替换为运行阻塞和 5 秒内的延迟时。它以总共 5 秒的时间并行运行(有 6 个实现,因此如果按顺序运行,则应该是 30 个)。所以这行得通。唯一的区别是我的实现使用事务查询数据库,并且此代码不在该类的协程上下文中运行。难道协程上下文只是类范围的。说起来很奇怪,但感觉就是这样。
  • 花费 2967 in milis 到 花费 62190 in milis 到 Total = 159966 in milis 为
  • 什么是actionImplementation 1、2和3?
  • 只是 ActionReportGetter 接口的实现。我省略了真实姓名

标签: spring kotlin kotlin-coroutines


【解决方案1】:

看起来您正在单线程环境中(可能在主线程中)在ActionReportGetter.getActions 中执行一些阻塞操作。 对于此类 IO 操作,您应该在 Dispatchers.IO 中启动您的协程,它提供了一个具有多个线程的线程池。

将您的代码更新为:

async(Dispatchers.IO) { // Switch to IO dispatcher
    getActions(actionReportGetter, abstractUser
}

getActions 在这里也不必是挂起函数。您可以从中删除 suspend 修饰符。

【讨论】:

  • 我认为这已经奏效了。我会做更多的测试,让你知道
  • 它成功了,我授予了这个职位。非常感谢!
  • 很高兴我能帮上忙 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
相关资源
最近更新 更多