actors in the jvm



Irving Cordova



http://irvingc.com


Threads considered harmful

Threads considered harmful

  • Synchronization

  • All memory is shared, so access must be synchronized

  • Deadlock

  • Use of shared resources that are locked opens the possibility of deadlocks

Threads considered harmful

  • Hard to debug

  • Bugs hard to reproduce, harder to fix

  • Hard to optimize

  • Locks create contention, which can slow performance.

Threads considered harmful

In short you need to be a wizard

alternatives?

John Ousterhout from Sun recommended event driven programming 

Alternatives?


Event driven model works. Node.js uses an event driven model and has been quite successful and very performant

Alternatives?


However, we are still bound to a single CPU

What if our event handlers lived in different processors?

The Actor ModeL


Everything is an actor.

Just like everything is an object in OOP.

The Actor Model


However while OOP is executed sequentially,
the actor model is executed concurrently 

The Actor Model

Communication happens not by function calls
but through messages

The Actor Model


There is no shared state

Actors only communicate through messages

Actors may create other actors

Actors may change its state after 
receiving a message

The Actor Model


No shared state eliminates contention


Without shared state, there is 
no need for synchronization

Surely not in my jvm


There have been a few programming 
languages that implement actors

Surely not in my JVM


Erlang famously has systems
with 99.9999999% uptime

Surely in my JVM!

There are a few Actor model 
implementations in the JVM. 

The project


Solve Quadratic Equations 
through actors

AkkA

sample code

  1. public class Greeting implements Serializable {
  2. public final String who;
  3. public Greeting(String who) { this.who = who; }
  4. }
  5.  
  6. public class GreetingActor extends UntypedActor {
  7. LoggingAdapter log = Logging.getLogger(getContext().system(), this);
  8.  
  9. public void onReceive(Object message) throws Exception {
  10. if (message instanceof Greeting)
  11. log.info("Hello " + ((Greeting) message).who);
  12. }
  13. }
  14.  
  15. ActorSystem system = ActorSystem.create("MySystem");
  16. ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");
  17. greeter.tell(new Greeting("Charlie Parker"));

Akka

Written in Scala
but has bindings to Java

Sometimes this implementation
 detail leaks

akka


Has a company behind it

Many fancy tools

Lets look at the code

AKKA


Pros


  • Conceptually simple
  • Can be used as a library
  • Not intrusive
  • Can use remote actors

AKKA


Cons


  • Cannot call new for actors

GPARS


Groovy Parallel System

GPARS


Written in Groovy

Has bindings to Java

Open Source

GPars

public class StatelessActorDemo {

public static void main(String[] args) throws InterruptedException { final MyStatelessActor actor = new MyStatelessActor(); actor.start(); actor.send("Hello"); actor.sendAndWait(10); actor.sendAndContinue(10.0, new MessagingRunnable<String>() { @Override protected void doRun(final String s) { System.out.println("Received a reply " + s); } }); } }

class MyStatelessActor extends DynamicDispatchActor { public void onMessage(final String msg) { System.out.println("Received " + msg); replyIfExists("Thank you"); }

public void onMessage(final Integer msg) { System.out.println("Received a number " + msg); replyIfExists("Thank you"); }

public void onMessage(final Object msg) { System.out.println("Received an object " + msg); replyIfExists("Thank you"); } }

GPars


Lets look at the code

Gpars


Pros


  • Very Simple to use
  • Integrates cleanly
  • Not intrusive
  • Clean code for receiving messages
  • Easy to reply to messages

Gpars


Cons


  • No support for remote actors
  • No built-in routing
  • There is not as much support
  • Groovy is not very performant

Jetlang


Jetlang


Message based concurrency in Java

(No direct reference to Actor model)

Open Source

Very low activity on the project

JETLANG

code sample

Fiber fiber = new ThreadFiber();
fiber
.start();
final CountDownLatch latch = new CountDownLatch(2);
Runnable toRun = new Runnable(){
   
public void run(){
      latch
.countDown();
   
}
};
//enqueue runnable for execution
fiber
.execute(toRun);
//repeat to trigger latch a 2nd time
fiber
.execute(toRun);

latch
.await(10, TimeUnit.SECONDS);

//shutdown thread
fiber
.dispose();

Jetlang


Lets look at the code

Jetlang


Pros


  • Fast
  • Open Source
  • No external dependencies
  • Explicit control over channels and threads

Jetlang


Cons


  • Syntax to use it is very obtrussive
  • Programmer must become well acquainted with library
  • Sometimes awkward to program

Questions?


irving@irvingc.com