I have read that, when using react, all actors can execute in a single thread. I often process a collection in parallel and need to output the result. I do not believe System.out.println is threadsafe so I need some protection. One way (a traditional way) I could do this:
val lock = new Object
def printer(msg: Any) {
lock.synchronized {
println(msg)
}
}
(1 until 1000).par.foreach { i =>
printer(i)
}
println("done.")
How does this first solution compare to using actors in terms of efficiency? Is it true that I’m not creating a new thread?
val printer = actor {
loop {
react {
case msg => println(msg)
}
}
}
(1 until 10000).par.foreach { i =>
printer ! i
}
println("done.")
It doesn’t seem to be a good alternative however, because the actor code never completes. If I put a println at the bottom it is never hit, even though it looks like it goes through every iteration for i. What am I doing wrong?
As you have it now with your Actor code, you only have one actor doing all the printing. As you can see from running the code, the values are all printed out sequentially by the Actor whereas in the parallel collection code, they’re out of order. I’m not too familiar with parallel collections, so I don’t know the performance gains between the two.
However, if your code is doing a lot of work in parallel, you probably would want to go with multiple actors. You could do something like this:
The def is important. This way you’re actually creating multiple actors and not just flooding one.