multithreading - 从线程获取返回值,这个 Kotlin 代码线程安全吗?
问题描述
我想跑一些踏板,等到所有踏板都完成并得到结果。
可能的方法是在下面的代码中。它是线程安全的吗?
import kotlin.concurrent.thread
sealed class Errorneous<R>
data class Success<R>(val result: R) : Errorneous<R>()
data class Fail<R>(val error: Exception) : Errorneous<R>()
fun <R> thread_with_result(fn: () -> R): (() -> Errorneous<R>) {
var r: Errorneous<R>? = null
val t = thread {
r = try { Success(fn()) } catch (e: Exception) { Fail(e) }
}
return {
t.join()
r!!
}
}
fun main() {
val tasks = listOf({ 2 * 2 }, { 3 * 3 })
val results = tasks
.map{ thread_with_result(it) }
.map{ it() }
println(results)
}
附言
Kotlin 中是否有更好的内置工具可以做到这一点?像使用 10 个线程池处理 10000 个任务吗?
它应该是线程,而不是协程,因为它将与遗留代码一起使用,我不知道它是否适用于协程。
解决方案
似乎JavaExecutors
正是这样做的
fun <R> execute_in_parallel(tasks: List<() -> R>, threads: Int): List<Errorneous<R>> {
val executor = Executors.newFixedThreadPool(threads)
val fresults = executor.invokeAll(tasks.map { task ->
Callable<Errorneous<R>> {
try { Success(task()) } catch (e: Exception) { Fail(e) }
}
})
return fresults.map { future -> future.get() }
}
推荐阅读
- jquery - 在 DataTables 列过滤选择上设置占位符
- python - 如何使用条件迭代熊猫行以创建新列?
- android - 如何从我的 Android Native App 中检测已安装的 Chrome 版本?
- jenkins - Jenkins 声明式管道:矩阵构建轴的顺序执行
- javascript - 如何在 Backbone js 中保留表单值?
- typescript - 仅从 typescript 模块导入类定义
- maven - 如何读取代码中的maven插件属性
- docusignapi - 将数据注入到所有收件人都可以看到的 Docusign 文档中
- node.js - 节点不断恢复到旧版本
- c++ - 如何将宏参数插入变量 C++ 处理器?