No wonder, so, if many languages come to our rescue by supporting concurrent programming through first-class syntax support, or through higher level user libraries.
Two well-known languages providing explicit concurrent programming support are Erlang and Scala, and both have in common the same concurrency model: actors.
The actor model is a concurrency abstraction based on the concepts of message-passing concurrency: very different from the shared state concurrency model we're used to in general purpose languages such as Java, but more efficient and easier to program with.
Let's see the difference between the two.
Shared-state concurrency is based on two fundamental concepts: resource sharing and resource synchronization.
As already said, it's the most common scenario with general purpose OO languages such as Java: it's composed by computational units (often implemented as threads) concurrently executing code sections containing resources that must be shared, and hence, synchronized in order to guarantee correct ordering, visibility and data consistency.
Message-passing concurrency, also known as share-nothing concurrency, is the exact opposite: here, computational units are just endpoints exchanging immutable messages one another, and reacting to received messages by executing a given computation.
In such a concurrency model, so, there isn't any shared resource, nor there is any need for resource synchronization: messages are immutable, and each computational unit is only able to change its own state in response to a received message.
It has several interesting consequences, making message-passing concurrency preferable over shared-state one:
- Message-passing concurrency is safer: there are no shared resources, so there is no possibility to corrupt data due to concurrent access.
- Message-passing concurrency is faster: there is no resource synchronization, so there are no bottlenecks, deadlocks, livelocks, or similar locking issues.
- Message-passing concurrency is easier: once you get used to the new paradigm, not to have to think at how to share and synchronize resources, is a big relief.
The actor concurrency model is a form of message-passing concurrency, based on:
- Actors: the computational units capable of sending messages and reacting to received ones by executing a given function.
- Messages: the form of communication used by actors in order to exchange data and carry on some kind of computation based on that data.
- Mailboxes (or channels): a kind of buffer every actor has for storing received messages which haven't been processed yet.
Every actor can communicate with other actors by obtaining their mailbox (or channel) "address", and then sending a message to it: this is the only way an actor has for changing the state of the system.
Every actor can receive messages and process them by executing a behavior function: such a function can only change the state of the actor itself, or send new messages to other actors (already existent or created on-the-fly).
Communication between actors is completely asynchronous and decoupled: that is, actors do not block waiting for responses to their messages; they just send messages and forget, reacting to incoming messages without any correlation to previously sent messages.
A concurrent system implemented trough the actor concurrency model is considered to be:
- Parallel: several actors can process several messages in parallel, each one independently from the other.
- Scalable: actors can be implemented in several ways, as local computational units or distributed ones, so
they can easily scale out to the number of available processors or computers. - Reconfigurable: actors can be dynamically added and removed from the system, and then communicate the new topology through special purpose messages.
Obtaining such a properties through a shared-state implementation is harder and requires a lot of challenges.
The actor model provides instead a well-defined, clearly stated way to easily build highly concurrent systems, at a cost of a paradigm shift.
Next time we will see how to implement an actor-based concurrent application through our favorite OO language: Java!
9 comments:
Nice Post Sergio, very instructive.
Thanks
Well done, Sergio!
Thanks guys for your positive feedback!
Sergio B.
Hi Sergio,
the actor model is known since sometimes in the scientific community.
You can find paper refs here:
http://dblp.uni-trier.de/rec/bibtex
/conf/coordination/HallerO07
or, a journal version of the paper, publised at ECOOP, at:
lamp.epfl.ch/~phaller/doc/haller07coord.pdf
The author is also the Scala Language's main designer.
In the end, I believe that the Actor model is simply the natural evolution of the event-based paradigm..
wdyt ?
Very interesting post Sergio, Thanks
One thing about actor concurrency that I haven't been able to wrap my head around is managing consistency. Let say I send messages to two actors. The change that is made to each actor as a result of the messages is somewhat related. This opens the door for other actors to observe those two in an inconsistent state. For example, maybe one actor is a baseball player and another is a team. The player is being traded. I need to tell the player actor that they are on a new team and I need to tell the team actor that they have lost a player.
Hi Mark,
if you have to implement atomic/transactional message exchanges, Actors alone are probably a bad fit: you may want to use Software Transactional Memory (STM), or maybe combine message passing and STM together.
Here is a good talk on such a topic: http://www.slideshare.net/jboner/state-youre-doing-it-wrong-javaone-2009
Hope it helps,
Cheers,
Sergio B.
If Buy GW2 Gold do not have got which can on your own that you are a new badass mofo and may win tourneys together with keyboard transforming, D3 Gold discover how to utilize the mouse to change your current persona;-- I am not sure just what otherwise to provide.
Obtaining such a properties through a shared-state implementation is harder and requires a lot of challenges.
http://www.meizu-mx5.com/
Post a Comment