轻量级的Scala fork连接语法 [英] A light weight Scala fork join syntax
问题描述
尽管即将推出Java 7标准fork/join框架,但我正在构建一些帮助程序方法,该方法的语法轻巧,可以让客户端并行运行代码. 这是一个可运行的主要方法来说明这个想法.
Despite the upcoming java 7 standard fork/join framework, I am building some helper method that is light weight in syntax for client to run code in parallel. Here is a runnable main method to illustrate the idea.
import actors.Futures
object ForkTest2 {
def main(args: Array[String]) {
test1
test2
}
def test1 {
val (a, b, c) =fork({
Thread.sleep(500)
println("inside fx1 ",+System.currentTimeMillis)
true
}, {
Thread.sleep(1000)
println("inside fx2 ",+System.currentTimeMillis)
"stringResult"
}, {
Thread.sleep(1500)
println("inside fx3 ",+System.currentTimeMillis)
1
})
println(b, a, c)
true
}
def test2 {
val results = forkAll({
() =>
Thread.sleep(500)
println("inside fx1 ",+System.currentTimeMillis)
true
}, {
() =>
Thread.sleep(1000)
println("inside fx2 ",+System.currentTimeMillis)
"stringResult"
}, {
() =>
Thread.sleep(1500)
println("inside fx3 ",+System.currentTimeMillis)
1
}, {
() =>
Thread.sleep(2000)
println("inside fx4 ",+System.currentTimeMillis)
1.023
})
println(results)
true
}
val tenMinutes = 1000 * 60 * 10
def fork[A, B, C](
fx1: => A,
fx2: => B,
fx3: => C
) = {
val re1 = Futures.future(fx1)
val re2 = Futures.future(fx2)
val re3 = Futures.future(fx3)
//default wait 10 minutes
val result = Futures.awaitAll(tenMinutes, re1, re2, re3)
(
result(0).asInstanceOf[Option[A]],
result(1).asInstanceOf[Option[B]],
result(2).asInstanceOf[Option[C]]
)
}
type fxAny = () => Any
def forkAll(
fx1: fxAny*
): List[Any] = {
val results = fx1.toList.map {fx: fxAny => Futures.future(fx())}
Futures.awaitAll(tenMinutes, results: _*)
}
}
输出的样本是
(inside fx1 ,1263804802301)
(inside fx2 ,1263804802801)
(inside fx3 ,1263804803301)
(Some(stringResult),Some(true),Some(1))
(inside fx1 ,1263804803818)
(inside fx2 ,1263804804318)
(inside fx3 ,1263804804818)
(inside fx4 ,1263804805318)
List(Some(true), Some(stringResult), Some(1), Some(1.023))
测试1说明了类型安全返回类型
test 1 illustrate a type safe return type
测试2说明了任意输入参数
test 2 illustrate a arbitrary input argument
我希望将两种测试方法结合起来,以便客户端代码可以与类型安全返回类型并行运行任意函数.
I hope to combine the two test method so the client code can run arbitrary function in parallel with type safe return type.
关于任意函数参数的另一点是:
Another point about the arbitrary function arguments is:
我认为这条线
type fxAny = () => Any
应该真的是代码
type fxAny = => Any
,但是scala编译器不允许我这样做.
, but the scala compiler do not allow me to do so.
感谢您的帮助.
推荐答案
Eric Torreborre在@retronym提供的链接中写道:
Eric Torreborre wrote in the link provided by @retronym:
trait LazyParameters {
/** transform a value to a zero-arg function returning that value */
implicit def toLazyParameter[T](value: =>T) = new LazyParameter(() => value)
/** class holding a value to be evaluated lazily */
class LazyParameter[T](value: ()=>T) {
lazy val v = value()
def apply() = v
}
}
这是您的测试的LazyParameter版本:
Here's LazyParameter version of your test:
object ForkTest2 extends LazyParameters {
...
def forkAll(fx1: LazyParameter[Any]*): List[Any] = {
val results = fx1.toList.map {
fx: LazyParameter[Any] => Futures.future(fx.apply())}
Futures.awaitAll(tenMinutes, results: _*)
}
编辑:您已经注意到,隐式评估by-name参数,并且不会延续评估延迟.为什么不只使用future
一词呢?我个人认为这会使代码更具可读性.
Edit: As you've noticed, implicit evaluates the by-name parameter and it doesn't carry forward the evaluation delay. Why not just use the word future
? I personally think it makes the code more readable.
import actors.Futures
import actors.Futures.future
import actors.Future
...
def test2 {
val results = forkAll(
future {
Thread.sleep(500)
println("inside fx1 ",+System.currentTimeMillis)
true
},
future {
Thread.sleep(1000)
println("inside fx2 ",+System.currentTimeMillis)
"stringResult"
},
future {
Thread.sleep(1500)
println("inside fx3 ",+System.currentTimeMillis)
1
},
future {
Thread.sleep(2000)
println("inside fx4 ",+System.currentTimeMillis)
1.023
})
println(results)
true
}
...
def forkAll(futures: Future[Any]*): List[Any] = {
println("forkAll")
Futures.awaitAll(tenMinutes, futures: _*)
}
这篇关于轻量级的Scala fork连接语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!