Why can you have millions of actors in an application, but just 10,000 threads is too many? How is it that creating millions of actors is practical, but more than a couple threads is not? What can threads do that actors can't (or else we would use actors all the time!)?
Assuming Scala and JVM:
Each thread reserves some amount of memory for its stack:
java -v
-Xss<size> set java thread stack size
So creating many threads will eat up your memory.
Multiple actors on the other hand may share the same stack thus being much less hungry on memory.
Actors and Threads are not the same kind of object.
* A thread is an actual object on your machine - it eats a predictable amount of ressources, and has an precise overhead associated with it. Hence, if you describe 1,000,000 tasks by means of giving each of them a thread, you are explicitly asking your machine for 1,000,000 times the resources of one thread.
* An actor is more of a way of explaining to your language a task unit, so it does not have a precise image at run time. Your compiler has much more freedom in using resources as it sees fit to accomplish the task you describe.
Threads are limited in their numbers precisely because they do eat resources in a precisely defined way. They consume memory, and switching to another thread has a cost. Past a certain number of threads, you will exhaust the machine's memory, or the scheduling costs will dominate your program execution. This is the kind of limit you will reach with many threads. And for all practical purposes, on today's hardware 10,000 threads is a lot.
But actors allow you to explain what you want to do in a way that is easier to understand to your programming language. As such, it can manage ressources in a much more efficient way, so that if you describe 1,000,000 tasks with actors, the environment has a much better chance to find a way to compile and run it so that it is still manageable. With respect to threads, most of the difference stems from the fact that when actors are describing a very distinct processing they can be run on any thread, allowing for schemes using an arbitrarily-sized pool of threads to process requests as they arrive. You don't lock the compiler in a scheme that will kill its performance : it knows it can't spawn 1,000,000 threads so it will try to accomplish it another way, and will often succeed. Freedom in deciding the number of threads allows for much optimization, the first of which using as many threads an there are cores/CPU on the machine, which yields optimal computational speed. Such a design is also much more resilient to deadlock problems since you don't deal directly with timing and locking.
As for what threads can do and not actors, there is not much, but threads being a closer representation of what is actualling happening in your machine, you have more close control on what is actually happening. So with threads, it is theoritically possible to achieve more performance, though in actuality using threads to beat a good compiler armed with Actors borderlines on the impossible, because the model is so much harder to use, and because the compiler knows so many things that are about impossible for you to know.
Another thing, albeit not a theoritical limitation, that Threads make possible and that actors won't be very good at, is dealing with libraries that use Threads. Indeed, threads is the base model of many environments and you have many libraries requiring you to use them in a specific manner. Actors may not be very able at that.
I can still think of another thing threads can do and not actors : real-time (I mean hard real time as in microsecond-order deadline, nano-second order jitter and code proofs and hard guarantees). I think it's possible to do real-time using an actor model, but as far as I'm aware, there is no such implementation, so until then you strictly have to do hard real-time with threads.
So why haven't we been using actors from the very beginning ? It's like many good things in programming : it took time and experience understanding better models and implementing them. We have much better tools and languages on average than we used to 30 years ago, and it is the same thing with Actors. It emerged more recently as a better way to do concurrency.
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