我读过,使用反应时,所有演员都可以在单个线程中执行。我经常并行处理一个集合,并需要输出结果。我不相信System.out.println是线程安全的,所以我需要一些保护。一种方法(传统方式),我可以这样做:使用斯卡拉演员的麻烦
val lock = new Object
def printer(msg: Any) {
lock.synchronized {
println(msg)
}
}
(1 until 1000).par.foreach { i =>
printer(i)
}
println("done.")
这是如何第一个解决方案比较,在效率方面使用的演员?是不是真的,我没有创建一个新的线程?
val printer = actor {
loop {
react {
case msg => println(msg)
}
}
}
(1 until 10000).par.foreach { i =>
printer ! i
}
println("done.")
但是,它似乎不是一个好的选择,因为演员代码永远不会完成。如果我在底部放置println,它将永远不会被击中,即使它看起来像是经历了每次迭代i
。我究竟做错了什么?
有时,即使执行完成,Scala终端也会变得有趣并且“挂起”。不完全确定原因,但在输出所有值后必须按Enter键。 –
我希望最终会显示一个'println(“done。”)“,但它不是('2.9.1.r0-b20110831114755')。 – schmmd
就好像在打印大部分数字之前“正在完成”一样。尝试从(1到10)运行,你应该得到相同的结果。至于这种行为的原因,演员是异步的。消息被发送,循环退出,并且在演员处理所有消息之前,程序的其余部分结束。 –