ActiveJava

Copyright Tristan Aubrey-Jones May 2008.

Abstract: A project investigating and developing an implicitly concurrent programming language, based on a metaphor taken from the physical world is reported. Uses a programming paradigm where programs consist of systems of autonomous agents, or active objects which communicate via message passing. A language enhancing Java with actors and linear types is presented. Example programs are written, compiled, and executed to evaluate the usefulness of the language. The language found to provide a familiar notation for implicit parallelism, and a compelling new model for concurrency, combining the performance of shared variables with the elegance of message passing.

Introductory Slides (PDF), Report (PDF),
ActiveJava compiler prototype (ajavac), ActiveJava runtime library (ajava_lang).

Examples:

calc - pocket calculator actor program
dining - dining philosophers actor program (never deadlocks)
sort - parallel quicksort implementation ("SortBenchmark" sorts 10,000 random integers using actors, java threads, and sequentially and compares)
To compile examples use:
compile.bat ./calc
compile.bat ./sort
compile.bat ./dining
To run examples use:
run ./calc Main
run ./dining Main
run ./dining Main fast
run ./sort Main
run ./sort SortingBenchmark

Philosopher.ajava

home Home   up Up   ( Download )


import java.util.Random; public aclass Philosopher { private int id; private Table table; private Fork lhf, rhf; private int state; public Philosopher(Table table, int id) { this.table = table; this.id = id; this.state = State.THINKING; printStatus("thinking"); randomDelay(); } // begins thinking, moves forks back // to the table, and delays a random time private void think() { // give forks back table <-- new MoveForks(id, lhf, rhf); // remember: lhf and rhf are destructive reads // as are linear objects // change state state = State.THINKING; // think for random time randomDelay(); printStatus("thinking"); } // becomes hungry, and announces to table // that it is hungry public static class IsHungry { public int id; public IsHungry(int id) { this.id = id; } } private void hungry() { state = State.HUNGRY; printStatus("hungry"); table <-- new IsHungry(id); } // receives forks simultaneously, and // begins to eat public react (MoveForks frks) { this.lhf <-- frks.lhf; this.rhf <-- frks.rhf; eat(); } // eats for a random time private void eat() { state = State.EATING; randomDelay(); printStatus("eating with fork " + Integer.toString(lhf.getId()) + " and " + Integer.toString(rhf.getId())); } // displays philosophers id and status private void printStatus(String status) { Stdout <-- "Philosopher " + Integer.toString(id) + " is " + status + "\n"; } // uses clock pulses, and a random countdown // to delay for a random period when thinking // and eating. private static final Random RNG = new Random(); private int countdown; private void randomDelay() { countdown = RNG.nextInt(10) + 1; } public react (Clock.Tick t) { countdown--; if (countdown == 0) proceed(); } private void proceed() { if (state == State.THINKING) { hungry(); } else { if (state == State.EATING) { think(); } else; } } }