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?
A thread is a "sequence of activity" - independent of specific objects. It can execute code that belongs to arbitrary objects. Whereas an actor is about a specific object that "owns" its own "sequence of activity".
An actor is a computational entity that, in response to a message it receives, can concurrently: send a finite number of messages to other actors; create a finite number of new actors; designate the behavior to be used for the next message it receives.
The actor model is a computer science concept that uses "actors" as the fundamental agents of computing. Actors take input, send output and perform functions. They can also create other actors.
Increasing the number of threads doesn't increase performance capacity (as you pointed out) but it also drains CPU time by giving the kernel more work to do. Basically, there are diminishing returns on threading and doing too much causes performance retrograde.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With