when is actor not appropriate?
I use actors whenever I need to run two threads concurrently. I don't ever use threads explicitly.
someone told me that act开发者_开发技巧ors are quite heavy and it is not always a good idea to use them.
What are the right scenarios to use actors and when not to use them?
Some of my actors just have a loop but no react. Is this a good practice?
[EDIT]
- Is it bad practice to use Thread.sleep inside the loop of an Actor?
Actors provide a distributed asynchronous algorithm with message passing model of computation, and is most adequate for tasks that fit that model.
Scala's actors can share memory, making it adequate for algorithms that rely on memory sharing, but not particularly so because you give up actor's main advantages. On the other hand, there's no particular disadvantage either.
See Distributed Computing on the wikipedia for more information.
There are two main classes of tasks that are not particularly good fit:
Tasks that depend heavily on synchronism
This is not really related to locks, or waiting for something before beginning something else. The main characteristic of synchronous systems is a heavy dependency on temporal ordering of tasks.
For example, if you need to know which task finished first, then actors lack of guarantee of ordering of messages make them a bad fit.
Tasks that are inherently data parallel
This is the situation where the same computation is performed over different chunks of data, with no dependency between them.
The "map" part of map-reduce algorithms fit this case.
While actors can do this, the same thing can be done with fork/join setups with less overhead. Scala 2.9 will have parallel collections targeted at this type of task.
Well, it is easy to assume that just because two pieces of code are running is different threads as follows:
new Thread(work1).start()
new Thread(work2).start()
That they must be running concurrently. Of course, this is not necessarily the case, and will be determined, largely, by the OS. So, it is possible that by splitting a piece of sequential work into large numbers of parallel sub-computations, all you are doing is creating an overhead of object creation and context-switching.
However, the ForkJoin framework, which sits underneath Scala's actor system is supposed to appropriately-size its internal pool of threads. This removes the unnecessary context-switching overhead, leaving only the overhead of any (possibly unnecessary) object/creation
According to the edit of question, it seems that you are using Actors to run a single operation, which is not the purpose of actor model. The inventor of the Actor-Model is saying clearly that "One actor is no actor", meaning that in order to use the actor model one should use it as a whole system.
So, Actor should run the code inside your loop, rather than running the loop itself. Then the actor should (asynchronously) get messages and act according to the message type and parameters. Think of it as a queue of instructions to make the actor do stuff.
@Jus12 - the scenario that you described is best handled by using Akka IO. The I/O examples provided in their documentation are simple, small, and easily understood. One actor, provided by Akka IO is responsible for the low level I/O; a second actor is provided by you to monitor and restore the connection, and the third actor is provided by you to do the "real" I/O.
Testing of those actors is very simple as well. Use the AkkaTestKit and see that each actor responds as expected to a very simple set of inputs.
In many cases, the overhead of using the Akka library more than pays for itself in reduced maintenance of your application.
精彩评论