8

我想生成一个线程并在该线程中运行代码。Scala中有哪些选项?

示例用法如下所示:

Thread.currentThread setName "MyThread"

val myThreadExecutor = ???

val threadNamePromise = Promise[String]

future {
  myThreadExecutor run {
    val threadName = "MySpecialThread"
    Thread.currentThread setName threadName
    threadNamePromise success threadName
  }
}

Await.result(threadNamePromise.future, Duration.Inf)

future {
  myThreadExecutor run {
    println(Thread.currentThread.getName) // MySpecialThread
  }
}

future {
  myThreadExecutor run {
    println(Thread.currentThread.getName) // MySpecialThread
  }
}

println(Thread.currentThread.getName)   // MyThread

我可以使用内置的 Scala 库中的任何内容吗?

编辑

我更新了片段以更好地反映意图

4

4 回答 4

7

就在这里。您可以使用scala.concurrent标准库中的。更具体地说,您可以使用期货 - 高度可组合的异步计算。

import java.util.concurrent.Executors
import concurrent.{ExecutionContext, Await, Future}
import concurrent.duration._

object Main extends App {

  // single threaded execution context
  implicit val context = ExecutionContext.fromExecutor(Executors.newSingleThreadExecutor())

  val f = Future {
    println("Running asynchronously on another thread")
  }

  f.onComplete { _ =>
    println("Running when the future completes")
  }

  Await.ready(f, 5.seconds) // block synchronously for this future to complete

}

Futures 在执行上下文中运行,这是线程池的抽象。此上下文可以隐式传递。在上面的示例中,我们使用了一个由 Scala 库定义的全局变量——但是您可以通过分配许多执行上下文来控制程序的这一方面。

该片段仅执行您要求的操作 - 同时运行代码。然而,future 远不止于此——它们允许您异步计算值、组合多个future 以获得它们之间存在依赖关系的结果,或者并行计算。

这是一个介绍:http ://docs.scala-lang.org/overviews/core/futures.html

于 2013-04-02T20:50:32.020 回答
3

使用@alexwriteshere 的答案作为基础,我创建了这个实现:

import java.util.concurrent.Executors
import scala.concurrent.future
import scala.concurrent.JavaConversions.asExecutionContext

class ApplicationThread {
  protected implicit val context = 
    asExecutionContext(Executors.newSingleThreadExecutor())

  def run(code: => Unit) = future(code)
}

更新

感谢@Dth 指出这是现代版本:

import java.util.concurrent.Executors
import scala.concurrent.{ExecutionContext, Future}

class ApplicationThread {
  protected implicit val context = 
    ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor())

  def run(code: => Unit) = Future(code)
}
于 2013-04-02T21:30:37.990 回答
2

除了标准并发库之外,还有更多。例如,有com.twitter/util-core库可以让您执行以下操作:

val pool = FuturePool.unboundedPool
pool {
   <code>
}

您的示例如下所示:

Thread.currentThread setName "MyThread"

// because you have to be using a single-threaded one to get the same name
val pool = FuturePool(Executors.newSingleThreadExecutor())

pool {
  Thread.currentThread setName "MySpecialThread"
}

pool {
  println(Thread.currentThread.getName) // MySpecialThread
}

println(Thread.currentThread.getName)
于 2013-04-02T20:45:04.817 回答
1

基于@EECOLOR回答,这是一个通用的、可重用的方法,它在单独的线程上执行任意代码:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

def executeParallelTask[T](code: => T): Future[T] = Future(code)
于 2018-05-25T21:45:22.617 回答