/* Generic Threads for Asynchronous Read/Write (binary) with callbacks. Built-in Runnable interface only requires public void run() method */ import java.io.*; interface AsynchCallBack { void callback(); } class AsynchRead extends Thread { protected DataInputStream din; protected byte[] buffer; // pointer to external buffer protected int si; // starting index to read into protected int len; // number of bytes to read protected AsynchCallBack actOnComplete = ()->{}; // default does nothing public AsynchRead(DataInputStream d, byte[] b, int i, int l, AsynchCallBack cb) { din=d; buffer = b; si=i; len=l; actOnComplete=cb; } public void run() { try { int n = 0; while (n{}; // default does nothing public AsynchWrite(DataOutputStream d, byte[] b, int i, int l, AsynchCallBack cb) { dout=d; buffer = b; si=i; len=l; if (actOnComplete!=null) actOnComplete =cb; } public void run() { try { dout.write(buffer,si,len); actOnComplete.callback(); } catch(IOException ie) {System.out.println(ie);} }//run }//AsynchRead // adaptor for arbitrary asynch operations with callback class AsynchOp extends Thread { protected Runnable job = ()->{}; protected AsynchCallBack actOnComplete = ()->{}; public AsynchOp(Runnable r, AsynchCallBack cb) { if (r!=null) job = r; if (cb!=null) actOnComplete=cb; } public void run() { job.run(); // not asynch.start! actOnComplete.callback(); } } //// sample usage // Let's see who can find the nth fibonacci number faster! public class callbacks { static int fib(int n) { if (n<3) return 1; else return fib(n-1)+fib(n-2);} static int cfib(int n) { double sq5 = Math.sqrt(5); double x = (Math.pow(1+sq5,n)-Math.pow(1-sq5,n)) / (Math.pow(2,n)*sq5); return (int)(x+0.5); // round off and return } static boolean checkpassword() { try { System.out.print("Enter password to get your Fibonacci number: "); String pw = new BufferedReader(new InputStreamReader(System.in)).readLine(); return "xyzzy".equals(pw); // password is xyzzy } catch (Exception e) {} return false; } public static void tjoin(Thread t) // join within try-catch { try { t.join(); } catch(InterruptedException ie) {System.out.println(ie);} } private static boolean checked = false; private static int f2 = 0; public static void main(String[] av) throws Exception // cheap { // check password and complete fibonacci calculation concurrently // boolean checked = false; // can't have real closures in java // int f = 0; AsynchOp checkpw = new AsynchOp( ()->{ checked=checkpassword(); }, null); checkpw.start(); AsynchJob fiber = new AsynchJob( ()->{ int f1=fib(45); tjoin(checkpw); return f1; }, (x)->{System.out.println("I'm fib, did I find the answer first? "+x); System.out.flush();}); AsynchOp cfiber = new AsynchOp( ()-> {f2 = cfib(45); }, ()-> {tjoin(checkpw); System.out.println("\nI'm the closed form and of course I found it first, modulo floating point errors."); System.out.flush();}); fiber.start(); cfiber.start(); cfiber.join(); if (checked) System.out.println("The answer is "+f2); System.out.flush(); // fiber.join(); // uses callback } } /////polymorphic versions: interface CallBack { void callback(T x); } interface OutputJob { OUT run(); } class AsynchJob extends Thread { protected OutputJob job = ()->null; protected CallBack actOnComplete = (x)->{}; public AsynchJob(OutputJob r, CallBack cb) { if (r!=null) job = r; if (cb!=null) actOnComplete=cb; } public void run() { actOnComplete.callback(job.run()); } }