views:

399

answers:

1

In Scala, if I have a simple class as follows:

val calc = actor {
  var sum = 0
  loop {
    react {
      case Add(n) => 
        sum += n
      case RequestSum =>
        sender ! sum
    }
  }
}

Should my field sum be marked @volatile? Whilst the actor is logically single-threaded (i.e. the messages are processed sequentially), the individual reactions may be happening on separate threads and hence the state variable may be being altered on one thread and then read from another.

+3  A: 

You don't need to mark them as volatile. The execution of your code isn't inside a synchronized block, but the actor will always pass through one before your code is invoked, thus forcing memory into a consistent state across threads.

Erik Engbrecht
Is this not a significant departure from Erlang then? It means that the actors are nor completely scalable with respect to the adding of cores - unless they are completely stateless.
oxbow_lakes
And couldn't the actors framework use the util.concurrent.Exchanger to hand off the state between threads?
oxbow_lakes
If a current value of something is only in a register of one CPU, and a stale value is in a shared cache or RAM, then it's fully possible for another CPU to see that stale value. @volatile tells the JVM that when a value is updated in one place, that update needs to propogate down before another thread tries to access that value (ok, I'm simplifying here...). Likewise, synchronized triggers the JVM to make sure all the different levels of memory are in a consistent state. This is a universal problem when dealing with multicore.
Erik Engbrecht
Is this only the case for an actor as declared above? For example, what if the actor was a subclass of Actor and overrode the act() method, referencing a non-volatile property declared elsewhere in the class. I see nothing in the actor codebase to suggest that this is thread-safe
oxbow_lakes