Suppose I have an actor that has a single field.开发者_如何转开发 99 out of every 100 messages to an actor read the value, and the 100th updates the value. In this case, I would like to process reads in parallel. In other words, how can I achieve the performance of Read/Write locks using Actors? Is this practical with Scala-standard actors or Akka? Or am I missing the point of actors :)
Update: fixed confusing language, sorry
[Disclaimer: I'm the PO of Akka]
I suggest using Agents instead, the read can be done at any point, but only one write at a time.
http://doc.akkasource.org/agents-scala
EDIT: http://doc.akka.io/docs/akka/2.1.0/scala/agents.html (try this link)
You're quite possibly missing the point of actors. I'm assuming you want an actor to which you send a query, and then it sends back a response. There's a fair amount of machinery involved in sending an actor a message, processing it, and sending a response back. The actual generation of the response message will be created as a task and submitted to a thread pool. Between the message queue and the thread pool there are multiple places that require locks or at best CAS operations. Usually the point is that the actor will do some work off in a separate thread based on that message.
If you just want to read and rarely write data (such as incrementing a counter, or access in a value in a map) you'll be much better off using an appropriate class from java.util.concurrent.
I assume you mean that all messages are immutable and that almost all messages do not mutate the state of the actor. In this case, actors are probably not the best choice of design. Actors allow you to manage any mutable state as if you were dealing with single threaded code.
Effectively, each actor has a mailbox to which messages are sent and then processed one at a time. In your scenario, this would be quite wasteful. As suggested, using something from java.util.concurrent would be most effective.
Actors are designed to process messages serially. This makes them easy to reason about: you get one message at a time, so any variables in the actor (as long as they are not mutated by anyone else) can be modified without thinking about concurrency. Is this the most efficient method? Absolutely not! But somewhat inefficient code that works correctly is almost always better than highly efficient code that is broken.
What you are asking for is the exact opposite: you want to think explicitly about concurrency ("I know that 99% of accesses will be reads and thus can occur in parallel!") in order to gain processing speed. In this case, you probably want to use java.util.concurrent.locks.ReentrantReadWriteLock
to directly control access to a mutable variable (if the type of access found in java.util.concurrent.atomic._
doesn't work for you). Just remember that you now have taken on the burden of getting locking right, and be appropriately careful.
精彩评论