|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
Using actors to access a shared resourceAsked this on stackoverflow, but my example domain kinda got in the way.
I wish to hash items and look them up by hash later. I wish to do this in a mult-threaded context, but have a single shared key/value/hasher. In Java, I would have something like: public class Hasher { /** Stores and returns hash */ public synchronized String store(Object o) { /* .. */ } /** Given hash, gets the stored object */ public synchronized Object get(String hash) { /* .. */ } } I'm told that the actor/message paradigm is a better way to handle concurrency, plus I'd like to learn more about how this works in Scala. So, if the key/value/hasher is an actor that receives messages and sends hashes/objects back to the sender, I see two ways to do this, neither of which is appealing:
Dave --- My Blog: http://www.naildrivin5.com/blog Scala Tour for Java Developers: http://www.naildrivin5.com/scalatour Fork me on Github: http://davetron5000.github.com |
|
|
Re: Using actors to access a shared resourceIf you're using 2.8, there's always
scala.collections.mutable.SynchronizedMap, which gives you the nicely atomic getOrElseUpdate() method. I'm not sure what the 2.7 equivalent is. Out of curiosity, why do you think that neither of your proposed options is appealing? On Sat, Nov 7, 2009 at 3:58 PM, David Copeland <davec@...> wrote: > Asked this on stackoverflow, but my example domain kinda got in the way. > > I wish to hash items and look them up by hash later. I wish to do this in a > mult-threaded context, but have a single shared key/value/hasher. > > In Java, I would have something like: > > public class Hasher { > /** Stores and returns hash */ > public synchronized String store(Object o) { /* .. */ } > > /** Given hash, gets the stored object */ > public synchronized Object get(String hash) { /* .. */ } > } > > I'm told that the actor/message paradigm is a better way to handle > concurrency, plus I'd like to learn more about how this works in Scala. > > So, if the key/value/hasher is an actor that receives messages and sends > hashes/objects back to the sender, I see two ways to do this, neither of > which is appealing: > > Client uses either a future or !? to block on the return > Client is also an actor that receives hash/Object in his act() method > > Is there another way, or is this just not something one should do with > Actors, or are the two options above not that bad? > > > Dave > > --- > My Blog: http://www.naildrivin5.com/blog > Scala Tour for Java Developers: http://www.naildrivin5.com/scalatour > Fork me on Github: http://davetron5000.github.com > > > |
|
|
Re: Using actors to access a shared resourceOne can @synchronized methods in Scala, so your Java example is directly translatable into Scala. Using the Actor paradigm one would use some sort of Store and Get message. Both ultimately use monitors to coordinate thread access. The Actor however has some additional overhead associated with Message construction/deconstruction/queueing/dequeueing.
Both approaches allow one to ensure one and only one thread is accessing state at any given time. Personally I would not use an Actor whose sole function was no more than synchronizing a collection data structure. One certainly could however. On a complete aside I do use Actors frequently and there is a usage pattern I use that I'm not sure I've seen mentioned. I'm think its safe. :) Often my Actor compartmentalizes quite a bit of state and all state updating behaviour occurs via messages. However, I may have one or more readers of simple internal state such as a counter, FSM state value etc. The Actor approach requires some variation of the following message set for the Actor {RequestCounterValue, CounterValueResponse, SetCounterValue}. However if one can ensure that state is mutated by one and only one thread, then multiple readers of state can safely read state values which are volatile. The single thread mutation constraint is given by the Actor. So I think the following is safe, but is unpure Actor behavior. case class SetCounter (x: Int) val a = actor { @volatile private counter: Int def count () = counter def act () { while (true) { receive { case SetCounter (x) => counter = x } } Multiple parallel readers should be able to invoke a.count without requiring a lock and safely read the counter value. In a sense a low level ReadWriteLock.
On Sat, Nov 7, 2009 at 10:58 AM, David Copeland <davec@...> wrote: Asked this on stackoverflow, but my example domain kinda got in the way. -- The object of life is not to be on the side of the majority, but to escape finding oneself in the ranks of the insane. - Marcus Aurelius |
| Free embeddable forum powered by Nabble | Forum Help |