I just learned about the actor model a while ago and decided to see if I could do something similar in Java. The result is pretty short, only 2 class and it works.
public class Message {
public final Object object;
public final Actor source;
public Message(Object object, Actor source){
this.object = object;
this.source = source;
}
}
import java.util.ArrayList;
import java.util.HashMap;
public abstract class Actor implements Runnable{
private Thread thread;
private ArrayList<Message> messageList = new ArrayList<Message>();
private HashMap<Object, ArrayList<Message>> waitMap = new HashMap<Object, ArrayList<Message>>();
private Object current = null;
private synchronized void add(Message m){
messageList.add(m);
notify();
}
private synchronized Message get(){
return messageList.remove(0);
}
private synchronized void waiting(){
if(messageList.size() == 0){
try { wait(); }
catch (InterruptedException e) { } //Do nothing
}
}
public void wait(Object key, Message m){
ArrayList<Message> list = waitMap.get(key);
if(list == null){
list = new ArrayList<Message>();
waitMap.put(key, list);
}
list.add(m);
}
public void notify(Object key){
ArrayList<Message> list = waitMap.get(key);
if(list != null && list.size() > 0){
Message m = list.remove(0);
add(m);
if(list.size() == 0){
waitMap.put(key, null);
}
}
}
public void notifyAll(Object key){
ArrayList<Message> list = waitMap.get(key);
if(list != null && list.size() > 0){
for(Message m : list){
add(m);
}
list.clear();
waitMap.put(key, null);
}
}
public void sleep(int milli){
try { Thread.sleep(milli); }
catch (InterruptedException e){ }; //Do nothing
}
public void println(Object o){
System.out.println(o);
}
public void println(){
System.out.println();
}
public void print(Object o){
System.out.print(o);
}
public void send(Object o, Actor actor){
if(actor != null){
actor.add(new Message(o, this));
}
}
public void act() {
thread = new Thread(this);
thread.start();
}
public void stop() {
thread.interrupt();
}
@Override
public void run() {
init();
while(!thread.isInterrupted()){
if(messageList.size() > 0){
Message m = get();
current = m.object;
receive(m);
}else{ waiting(); }
}
end();
}
public boolean is(Object o){
if(current == null){ return false; }
else{ return current.equals(o); }
}
public boolean isA(Object o){
if(current == null || o == null){ return false; }
else{ return o.getClass().isInstance(current); }
}
public <E> boolean isA(Class<E> c){
if(current == null || c == null){ return false; }
else{ return c.isInstance(current); }
}
public abstract void init();
public abstract void receive(Message m);
public abstract void end();
}