MessageApplet.java: import java.applet.Applet; import java.util.concurrent.LinkedBlockingQueue; import netscape.javascript.JSObject; public class MessageApplet extends Applet { class MessageWorker implements Runnable { LinkedBlockingQueue queue; MessageWorker () { queue = new LinkedBlockingQueue (); } void insertMessage (JSObject message) { try { queue.put(message); } catch (InterruptedException e) { // TODO } } public void run() { for (;;) { try { JSObject message = queue.take(); dispatchMessage (message); } catch (InterruptedException e) { // TODO } } } public void dispatchMessage (JSObject message) { System.out.println (message); Object [] noArgs = new Object [0]; Object [] oneArg = new Object [1]; int parameterCount = toInteger (message.call("getParametersLength", noArgs)); int localCount = toInteger (message.call("getLocalParametersLength", noArgs)); // skip local parameters for (int i = localCount; i < parameterCount; i++) { oneArg[0] = new Integer(i); String param = (String) message.call("getParameter", oneArg); // add something to parameter oneArg[0] = new String (param + "-Message worker-"+hashCode()); message.call("addResponse" , oneArg); } message.call("callback", noArgs); message.call("done", noArgs); } } static MessageWorker worker = null; static Object lock = new Object (); public void insertMessage (JSObject message) { worker.insertMessage(message); } public void init() { synchronized (lock) // maybe two applets starting at same time ? Probaly this should be an integer to count references and destroy when all others exits. { if (worker == null) { worker = new MessageWorker (); Thread thread = new Thread (worker); thread.start(); } } super.init(); } public static int toInteger (Object obj) { if (obj == null) return 0; if (obj instanceof Integer) // IE6 and Chrome { return ((Integer) obj).intValue(); } else if (obj instanceof Double) // FF 2.0 { return ((Double) obj).intValue(); } else if (obj instanceof String) // dont know { return Integer.parseInt((String) obj); } return 0; } public void destroy () { super.destroy(); } } HTML (with included javascript):

Test it