210 likes | 308 Views
Austin Java Users Group developerWorks article – µActor Library. Barry Feigenbaum, Ph. D. 02/26/13. Brief Bio. I have Ph.D. in Computer Engineering I have been developing software for more than 30 years I have worked at IBM, Amazon, Dell and others.
E N D
Austin Java Users GroupdeveloperWorksarticle – µActor Library Barry Feigenbaum, Ph. D. 02/26/13
Brief Bio • I have Ph.D. in Computer Engineering • I have been developing software for more than 30 years • I have worked at IBM, Amazon, Dell and others. • I have worked as a developer, designer, team lead, architect and manager • I have worked on business applications, operating systems, tools, web application, etc. • I have been using Java since version 1.0.2. • I am Oracle certified: Java Programmer, Java Developer, Architect for Java Technology • I have written several books and articles; I have numerous US patents
Topics • Background • Actor Library Design and Implementation • Sample Actor • Demo
Background • Moore’s Law: due to heat dissipation issues moving from faster and faster CPU speed to more copies (i.e., cores) of a CPU per processor • Most computers have multiple cores and the number is increasing over time • Automatic speed up no longer occurring; programsmust become much more concurrent to exploit these cores • Traditional imperative languages do this poorly • Hard to code; requires high skill • Near impossible to test correct implementations • Something simpler, such as the Actor Model, is needed
Background (cont) • Newer languages offering solutions • Concurrency Libraries • Built-in Language Facilities (ex. Actors; Functional (no side-effects) orientation) • Etc. • JRE provides support but at too low a level • threads • synchronized blocks • java.util.concurrent
µActor Library • This presentation concentrates on a Java library for exploiting the Actormodel • Wikipedia: The Actor model in computer scienceis a mathematical model of concurrent computation that treats "actors" as the universal primitives of concurrent digital computation: in response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and determine how to respond to the next message received. • This library can be used by any Java 6+ application http://www.ibm.com/developerworks/library/j-javaactors/index.html
µActor Library (cont) • Lightweight and easy to use • Pure-Java library (no AOP, etc.) • Configurable and dynamic • Key Concepts (interfaces with default implementations) • Actor – unit of execution; processes 1 message at a time • Message – defines an action, has from/to/subject/data/+ • ActorManager – manages actors; allocates threads to actors to process messages
Actor Runtime Model Per Message • Managers own 0+ Actors • Managersmanage 0+ Threads • Actors buffer 0+ Messages • Managers send messages to Actors • Actors use Threads to process messages Thread * Manager Actor * * Message
ActorManager • Actor lifetime management • Actor runtime lifecycle management • Message sending services • DefaultActorManager implementation • Adds more API, including thread pool management
Actor extends Runnable • Message processing and capacity • Distinct identity, category • Lifecycle, belongs to only one manager • AbstractActor partial implementation • Adds some more services • Multiple levels of subclasses possible
Actor Lifecycle Activated New • New • Activate • Run • Receive (repeated) • Deactivate • Garbage Run Idle Suspended Receive Consumes thread in receive state Shutdown Deactivated
Message • Message body • Sender, subject, data • Optional but typical • Target supplied via send operation • Added to message by send code • DefaultMessage implementation • Multiple levels of subclasses possible
Execution Model • Multiple actors, possibly of different types, cooperate by sending messages to each other. • Sends can fail - count limit exceeded, bad subject, etc. • Each actor has a queue of pending (received) messages. • When a thread is available, the manager dispatches an actor’s receive method passing in the next message. • Receive should be short lived
TestActor • A sample actor • Repeats sends count down • Define lifecycle callback methods (for illustration) • Define on start callback public class TestActor extends TestableActor { @Override public void activate() { super.activate(); } @Override public void deactivate() { super.deactivate(); } @Override protected void runBody() { DefaultMessage m = new DefaultMessage("init", 8); getManager().send(m, null, this); }
TestActor (cont) • Assume superclass has overridden receive to call loopBody • Process repeat message • Repeat send N-1 times to random actor @Override protected void loopBody(Message m) { String subject = m.getSubject(); if ("repeat".equals(subject)) { int count = (Integer) m.getData(); if (count > 0) { m = new DefaultMessage("repeat", count - 1); String toName = "actor" + ???; Actor to = actorTest.getTestActors().get(toName) getManager().send(m, this, to); }
TestActor (cont) • Process init message • Send count messages to random actors with random delays • Process other messages • Typically signal error or delegate to superclass } else if ("init".equals(subject)) { int count = (Integer) m.getData(); for (inti = 0; i < count; i++) { m = new DefaultMessage("repeat", count); String toName = "actor“ + ???; Actor to = actorTest.getTestActors().get(toName); getManager().send(m, this, to); DefaultMessagedm = new DefaultMessage("repeat", count); dm.setDelayUntil(new Date().getTime() + ???); getManager().send(dm, this, this.getClass().getSimpleName()); } } else { … } }
Example Main DefaultActorManager am = DefaultActorManager.getDefaultInstance(); : Map<String, Actor> testActors = new HashMap<String, Actor>(); for (inti = 0; i < 2; i++) { Actor a = am.createActor(TestActor.class, "common" + i); a.setCategory("common"); testActors.put(a.getName(), a); } for (inti = 0; i < 5; i++) { Actor a = am.createActor(TestActor.class, "actor" + i); testActors.put(a.getName(), a); } for (String key : testActors.keySet()) { am.startActor(testActors.get(key)); } for (inti = 120; i > 0; i--) { if (i < 10 || i % 10 == 0) System.out.printf("main waiting: %d...%n", i); delay(1000); } : am.terminateAndWait(); • Access an actor manager • Create some actors in the common category • Create some actors in the default category • Start all the actors • Keep main alive to allow actors to run • Terminate actor processing
Visualize running Actors • GUI shows any activity • Controls at top select example and control execution • Green bar shows active threads • Circle shows active actors and messages between them • Small squares show active threads • Lines show messages • Bottom circles show recent history • Right pane show log trace
Demo • No Example Selected • Countdown started • Most Busy • Staring to slow down • Slowing more • Near done • Done
Online Video of Demo http://www.youtube.com/watch?feature=player_embedded&v=1emMgwyI9Xk