static class Q implements AutoCloseable { S name = "Unnamed Queue"; BlockingQueue q = new LinkedBlockingQueue; volatile bool retired; static class Done extends RuntimeException {} *() {} *(bool startThread) { if (startThread) startThread(); } *(String *name, boolean startThread) { if (startThread) startThread(); } Runnable _mainRunnable() { ret r { Q.this.run(); }; } Thread startThread() { ret _startThread(name, _mainRunnable()); } Thread startDaemonThread() { ret _startThread(newDaemonThread(name, _mainRunnable())); } Iterable master() { return new Iterable() { public Iterator iterator() { return new Iterator() { Runnable x; public boolean hasNext() ctex { //debug("hasNext"); while (x == null && licensed() && !retired) x = q.poll(1, TimeUnit.SECONDS); //debug("hasNext true"); return true; } public Runnable next() { if (!licensed() || retired) 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() || retired) ret; try { r.run(); } catch (Done e) { ret; // break signal } catch (Throwable e) { printStackTrace(e); } } } // end after current items have been processed void done() { add(r { throw new Done; }); } public void close() { retired = true; } // TODO: interrupt thread bool isEmpty() { ret q.isEmpty(); } }