【发布时间】:2010-11-25 02:33:12
【问题描述】:
我想知道是否有一种方法可以在没有太多开销的 scala 中的另一个线程上执行非常简单的任务?
基本上,我想创建一个可以处理执行任意数量任务的全局“执行器”。然后我可以使用执行器来构建额外的构造。
此外,如果客户端不必考虑阻塞或非阻塞因素,那就太好了。
我知道 scala 演员库是建立在 Doug Lea FJ 的基础之上的,而且它们在一定程度上支持我想要完成的工作。但是据我了解,我必须预先分配一个“演员池”才能完成。
我想避免为此创建一个全局线程池,因为据我了解,它并不擅长细粒度并行。
这是一个简单的例子:
import concurrent.SyncVar
object SimpleExecutor {
import actors.Actor._
def exec[A](task: => A) : SyncVar[A] = {
//what goes here?
//This is what I currently have
val x = new concurrent.SyncVar[A]
//The overhead of making the actor appears to be a killer
actor {
x.set(task)
}
x
}
//Not really sure what to stick here
def execBlocker[A](task: => A) : SyncVar[A] = exec(task)
}
现在是使用 exec 的示例:
object Examples {
//Benchmarks a task
def benchmark(blk : => Unit) = {
val start = System.nanoTime
blk
System.nanoTime - start
}
//Benchmarks and compares 2 tasks
def cmp(a: => Any, b: => Any) = {
val at = benchmark(a)
val bt = benchmark(b)
println(at + " " + bt + " " +at.toDouble / bt)
}
//Simple example for simple non blocking comparison
import SimpleExecutor._
def paraAdd(hi: Int) = (0 until hi) map (i=>exec(i+5)) foreach (_.get)
def singAdd(hi: Int) = (0 until hi) foreach (i=>i+5)
//Simple example for the blocking performance
import Thread.sleep
def paraSle(hi : Int) = (0 until hi) map (i=>exec(sleep(i))) foreach (_.get)
def singSle(hi : Int) = (0 until hi) foreach (i=>sleep(i))
}
最后运行示例(可能要运行几次,以便 HotSpot 可以预热):
import Examples._
cmp(paraAdd(10000), singAdd(10000))
cmp(paraSle(100), singSle(100))
【问题讨论】:
标签: scala concurrency parallel-processing actor fork-join