I have an ActorSystem which has three actors, a MasterActor, a PrinterActor and a BlockerActor:
The PrinterActor simply sleeps for one second then prints out something:
public class PrinterActor extends UntypedActor {
@Override
public void onReceive(Object msg) throws Exception {
Thread.sleep(1000);
System.out.println("elapsed time is " + (System.currentTimeMillis()-(Long)msg));
}
}
The BlockerActor does some CPU-intensive work:
public class BlockerActor extends UntypedActor {
@Override
public void onReceive(Object msg) throws Exception {
long count=0;
for (int i=0; i<5000; i++) {
for (int j=0; j<1000000000; j++) {
count++;
}
}
System.out.println("count is " + count);
}
}
The MasterActor creates the above two actors then tells them to start working at the same time:
public class MasterActor extends UntypedActor {
@Override
public void onReceive(Object msg) throws Exception {
ActorRef printer = getContext().actorOf(Props.create(PrinterActor.class), "printerActor");
ActorRef blocker = getContext().actorOf(Props.create(BlockerActor.class), "blockerActor");
blocker.tell("start", getSelf());
printer.tell(System.currentTimeMillis(), getSelf());
}
}
The main method instantiates an ActorSystem, creates a MasterActor under it then sends the actor a start message.
public class App {
public static void main( String[] args ) {
ActorSystem actorSystem = ActorSystem.create("Test");
ActorRef master = actorSystem.actorOf(Props.create(MasterActor.class), "masterActor");
master.tell("start", null);
}
}
I expected the PrinterActor to finish fast but this was not the case. See the output below:
count is 5000000000000
elapsed time is 106856
It looks to me the PrinterActor didn't actually get a separate thread but was sharing a single thread with other two actors in the system. I'm having this impression because if I change the BlockerActor's implementation to:
public class BlockerActor extends UntypedActor {
@Override
public void onReceive(Object msg) throws Exception {
Thread.sleep(60 * 1000);
}
}
the PrinterActor would run much faster:
elapsed time is 1004
Note that I did not configure any dispatcher for my actors. So they should all be using the system's default dispatcher which has a pool of 3.0 (default parallelism-factor) * number of CPUs (8 cores in my machine) = 24 threads. I even tried to give the PrinterActor a PinnedDispatcher (dedicated thread) but still couldn't get the PrinterActor to speed up when my BlockerActor was working hard.
Now I'm really confused. Aren't you suppose to get some degree of parallelism when using actors like this? Is this an expected behavior of Akka or did I do anything wrong?
PS: I ran my program in Eclipse with Akka 2.3.6