Wednesday 15 January 2014

java - Akka actor blocked by another actor running CPU-intensive job -



java - Akka actor blocked by another actor running CPU-intensive job -

i have actorsystem has 3 actors, masteractor, printeractor , blockeractor:

the printeractor sleeps 1 sec prints out something:

public class printeractor extends untypedactor { @override public void onreceive(object msg) throws exception { thread.sleep(1000); system.out.println("elapsed time " + (system.currenttimemillis()-(long)msg)); } }

the blockeractor cpu-intensive work:

public class blockeractor extends untypedactor { @override public void onreceive(object msg) throws exception { long count=0; (int i=0; i<5000; i++) { (int j=0; j<1000000000; j++) { count++; } } system.out.println("count " + count); } }

the masteractor creates above 2 actors tells them start working @ 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 actorsystem, creates masteractor under sends actor 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 printeractor finish fast not case. see output below:

count 5000000000000 elapsed time 106856

it looks me printeractor didn't separate thread sharing single thread other 2 actors in system. i'm having impression because if alter blockeractor's implementation to:

public class blockeractor extends untypedactor { @override public void onreceive(object msg) throws exception { thread.sleep(60 * 1000); } }

the printeractor run much faster:

elapsed time 1004

note did not configure dispatcher actors. should using system's default dispatcher has pool of 3.0 (default parallelism-factor) * number of cpus (8 cores in machine) = 24 threads. tried give printeractor pinneddispatcher (dedicated thread) still couldn't printeractor speed when blockeractor working hard.

now i'm confused. aren't suppose grade of parallelism when using actors this? expected behavior of akka or did wrong?

ps: ran programme in eclipse akka 2.3.6

the issue thread.sleep there platform/implementation related issues.

http://www.jwrapper.com/blog/worst-bug-ever-java-sleeps-3-orders-of-magnitude-too-long https://community.oracle.com/thread/2576985

i tried illustration in scala , did not experience additional blocking printactor.

you can add together printout "internal" execution time verify if thread.sleep problem.

elapsed time 1005 (external)

elapsed time 1007 (internal)

counter 5000000000

package actors import akka.actor.{actorsystem, actor, props} class printactor extends actor { override def receive = { case externalstarttime: long => val internalstarttime = system.currenttimemillis() thread.sleep(1000) println(s"elapsed time ${system.currenttimemillis() - externalstarttime} (external)") println(s"elapsed time ${system.currenttimemillis() - internalstarttime} (internal)") case _ => throw new illegalargumentexception } } class blockeractor extends actor { override def receive = { case "start" => var counter = 0l (i <- 1 5000) { (j <- 1 1000000) { // 1000000000 counter += 1 } } println(s"counter $counter") case _ => throw new illegalargumentexception } } class masteractor extends actor { override def receive = { case "start" => val printer = context.actorof(props[printactor], "printeractor") val blocker = context.actorof(props[blockeractor], "blockeractor") blocker.tell("start", self) printer.tell(system.currenttimemillis(), self) case _ => throw new illegalargumentexception } } object app { def main (args: array[string]) { val actorsystem = actorsystem("test") val master = actorsystem.actorof(props[masteractor], "masteractor") master.tell("start", null) actorsystem.shutdown() } }

java multithreading akka blocking

No comments:

Post a Comment