如何在Kotlin中并发运行阻塞Java代码?
我正在进行一个新的副项目,目标是更深入地学习Kotlin,我在弄清楚如何将Kotlin风格的并发性与没有考虑到协同程序的代码(在本例中是JOOQ)混合在一起时遇到了一点困难。下面的函数在我的一个DAO中,在该映射块中,我想更新数据库中的一组行。在这个特定的示例中,更新实际上依赖于前一个完成的更新,因此需要按顺序执行,但我感兴趣的是如何修改此代码以并行运行更新,因为毫无疑问,我有一些用例不需要按顺序运行如何在Kotlin中并发运行阻塞Java代码?,kotlin,kotlin-coroutines,jooq,Kotlin,Kotlin Coroutines,Jooq,我正在进行一个新的副项目,目标是更深入地学习Kotlin,我在弄清楚如何将Kotlin风格的并发性与没有考虑到协同程序的代码(在本例中是JOOQ)混合在一起时遇到了一点困难。下面的函数在我的一个DAO中,在该映射块中,我想更新数据库中的一组行。在这个特定的示例中,更新实际上依赖于前一个完成的更新,因此需要按顺序执行,但我感兴趣的是如何修改此代码以并行运行更新,因为毫无疑问,我有一些用例不需要按顺序运行 suspend fun updateProductChoices(choice: Produc
suspend fun updateProductChoices(choice: ProductChoice) = withContext(Dispatchers.IO) {
ctx().transaction { config ->
val tx = DSL.using(config)
val previousRank = tx.select(PRODUCT_CHOICE.RANK)
.from(PRODUCT_CHOICE)
.where(PRODUCT_CHOICE.STORE_PRODUCT_ID.eq(choice.storeProductId))
.and(PRODUCT_CHOICE.PRODUCT_ID.eq(choice.productId))
.fetchOne(PRODUCT_CHOICE.RANK)
(previousRank + 1..choice.rank).map { rank ->
tx.update(PRODUCT_CHOICE)
.set(PRODUCT_CHOICE.RANK, rank - 1)
.where(PRODUCT_CHOICE.PRODUCT_ID.eq(choice.productId))
.and(PRODUCT_CHOICE.RANK.eq(rank))
.execute()
}
}
}
最好的方法是将
事务
lambda封装在运行阻塞
中,并将每个更新
封装在异步
中,然后等待所有结果?还可能值得注意的是,JOOQ查询支持executeAsync()
,它返回一个CompletionStage
是的,使用JOOQ的executeAsync
。使用executeAsync
,您可以删除withContext(Dispatchers.IO)
,因为调用不再阻塞
kotlinx-coroutines-jdk8
库包含与CompletionStage
的coroutines集成,因此您可以对其执行挂起wait
)
要并行执行更新,请注意,相同的库可以将CompletionStage
转换为延迟的()。因此,如果您将对execute
的调用更改为executeAsync().asDeferred()
,您将得到一个Deferred
s的列表,您可以在该列表上awaitAll()