我正在用spring Boot 和Kotlin构建一个后端应用。我想为一个特定的方法实现一个并行执行。我试图使用协程,但底层方法同步运行。
这就是我迄今为止所尝试的:
fun getXsByIds(xIds: List<String>): List<X> {
val xList = ArrayList<X>();
runBlocking {
val promises = xIds.map {
async {
getXById(it)
}
};
xList.addAll((promises.awaitAll()).filterNotNull())
}
return xList;
}
fun getXById(xId: String): X? {
// This method makes request to database
}
字符串
当我像这样把日志放在getXById
方法中时,
fun getXById(xId: String): X? {
print("start");
// This method makes request to database
print("end");
}
型
我得到这个输出
start
end
start
end
start
end
...
型
为什么我的协程不能并行工作?这是在Spring Boot 。不是被动的。线程每请求的风格。
2条答案
按热度按时间flmtquvp1#
调用
async
而不指定任何协程元素意味着它将从父协程继承所有协程元素(作业除外)。这将导致您的“runBlocking
”调用在runBlocking
的阻塞分派器上执行。尝试使用
async(Dispatchers.Default) { ... }
代替。u1ehiz5o2#
runBlocking
创建了一个ad-hoc协程调度器,它使用调用runBlocking
的线程来处理所有协程。这使它成为一个单线程调度器,这并不意味着它不能并发。它可以很好地运行任何数量的并发协程。但是,单线程分派器只有在使用挂起、非阻塞IO时才有效,而您的情况似乎并非如此。
这就是为什么你必须显式地指定
IO
调度器,它被设计为支持阻塞代码:字符串
虽然这解决了你眼前的问题,但你应该问问自己,如果你实际上没有使用暂停IO,为什么还要引入复杂的协同程序?坚持使用普通的Java Executor也会得到同样的结果。