How does Actors work compared to threads?

18,034

Solution 1

The actor model operates on message passing. Individual processes (actors) are allowed to send messages asynchronously to each other. What distinguishes this from what we normally think of as the threading model, is that there is (in theory at least) no shared state. And if one believes (justifiably, I think) that shared state is the root of all evil, then the actor model becomes very attractive.

We shouldn't get over excited, however. The actor model does not (contrary to some allegations) make it impossible to have deadlocks. The actor model also does not prevent you from having contention for resources between different processes -- message queues, for instance. The model is only "lock-free" above a certain level. At a lower level, for coordinating message queues, locking is still required.

Can't a thread be seen as an actor and send messages to other threads?

Well, yes and no. No, if you're just using the approach of putting mutexes around shared memory locations. Then the threads share this state -- they both have access to this memory, can both read it, re-write it, etc. But you can build an actor model on top of a threading model, and indeed all actor implementation do have threads underneath. I've hacked together something like this (very badly) by giving each thread a queue guarded by a mutex -- just for fun. To get an idea of how actor-thread impedance is managed, see my question from a year ago.

Can I use the Actor Model in any language by using threads differently?

Yes, but it'll take a bit more work. Your favourite language may well have a message-passing library, so that would be the first thing to investigate. Also, you should investigate the use of immutable data structures. Notice that if a data structure is immutable, then you've essentially dealt with the "shared-state" problem -- multiple threads can hold references to immutable data without anything bad happening. There's a reason why actor languages tend to also be functional languages (erlang, scala).

You may also want to have a look at Software Transactional Memory, which is a different but also compelling model. Clojure is my favourite example of that.

Solution 2

I wouldn't say that actors always pass messages asynchronously--that would be too slow. Case in point, the JActor project uses 2-way messages (request/response) to better model a method call. And most requests are serviced synchronously.

JActor (a Java library) also does not use locks. Only some atomic and concurrent data structures, with a few semaphores thrown in. Message passing is about .8 Billion messages per second.

https://github.com/laforge49/JActor

Share:
18,034
Jonas
Author by

Jonas

Passionated Software Developer interested in Distributed Systems

Updated on June 24, 2022

Comments

  • Jonas
    Jonas almost 2 years

    Is there any good and short explanation of how Actors works compared to threads?

    Can't a thread be seen as an actor and send messages to other threads? I see some difference, but it's not that clear for me. Can I use Actors in any language by using threads differently?

  • B T
    B T over 11 years
    The actor model is defined by only using asynchronous communication (en.wikipedia.org/wiki/Actor_model). If JActor isn't doing that, then it isn't 100% only the actor model. It may simply use the actor model as one-of-many of its features.
  • Piotr Kołaczkowski
    Piotr Kołaczkowski over 8 years
    The more I use asynchronous message passing based concurrency models (e.g. actors or async/await), the more I think they are just dual of the old, standard synchronized blocking concurrency model. Asynchronous message passing is not really any easier or any harder than using locks and monitors. Indeed, there is no shared mutable state, but only at the single actor level. But an actor still does have mutable state, and it is actually observable by all the actors that cooperate with it. Therefore you can have all the same problems: deadlocks, livelocks, starvation, race conditions, etc.