static class Q { BlockingQueue q = new LinkedBlockingQueue; static class Done extends RuntimeException {} Q() {} Q(bool startThread) { if (startThread) startThread(); } Q(String name, boolean startThread) { if (startThread) startThread(name); } Thread startThread() { ret startThread("Unnamed Queue"); } Thread startThread(S name) { Thread t = newThread(name, r { Q.this.run(); }); t.start(); ret t; } Iterable master() { return new Iterable() { public Iterator iterator() { return new Iterator() { Runnable x; public boolean hasNext() ctex { //debug("hasNext"); while (x == null && licensed()) x = q.poll(1, TimeUnit.SECONDS); //debug("hasNext true"); return true; } public Runnable next() { if (!licensed()) ret null; //debug("next"); hasNext(); Runnable _x = x; x = null; //debug("next " + structure(x)); return _x; } public void remove() { } }; } }; } void add(Runnable r) { q.add(r); } void add(O r) { q.add(toRunnable(r)); } void run() { for (Runnable r : master()) { if (!licensed()) ret; try { r.run(); } catch (Done e) { ret; // break signal } catch (Throwable e) { e.printStackTrace(); } } } void done() { add(r { throw new Done; }); } }