简体   繁体   English

从线程获取返回值,这个 Kotlin 代码线程安全吗?

[英]Get return value from thread, is this Kotlin code thread safe?

I would like to run some treads, wait till all of them are finished and get the results.我想跑一些踏板,等到所有踏板都完成并得到结果。

Possible way to do that would be in the code below.可能的方法是在下面的代码中。 Is it thread safe though?它是线程安全的吗?

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)
}

PS附言

Are there better built-in tools in Kotlin to do that? Kotlin 中是否有更好的内置工具可以做到这一点? Like process 10000 tasks with pool of 10 threads?像使用 10 个线程池处理 10000 个任务吗?

It should be threads, not coroutines, as it will be used with legacy code and I don't know if it works well with coroutines.它应该是线程,而不是协程,因为它将与遗留代码一起使用,我不知道它是否适用于协程。

Seems like Java has Executors that doing exactly that似乎 Java 的Executors正是这样做的

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() }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM