package cri.sanity.util; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.HashMap; import java.util.Map; import cri.sanity.Conf; public abstract class Task implements Runnable { public static class Pool extends ScheduledThreadPoolExecutor { public Pool() { super(3); } // FIX: leave 3??? } private static final Map<Integer,ScheduledFuture<?>> map = new HashMap<Integer,ScheduledFuture<?>>(16); private static Pool pool; private static int idCur = 0; //---- instance methods /* public final void exec() { if(pool == null) pool = new Pool(); pool.execute(this); } */ public final void exec(int delay) { if(pool == null) pool = new Pool(); pool.schedule(this, delay, TimeUnit.MILLISECONDS); } public final void exec(int id, int delay) { //synchronized(map) { final ScheduledFuture<?> sf = map.get(id); if(sf != null) sf.cancel(false); if(pool == null) pool = new Pool(); map.put(id, pool.schedule(this, delay, TimeUnit.MILLISECONDS)); //} } //---- static methods public static final int idCur() { return idCur; } public static final int idNew() { return ++idCur; } public static final boolean has(int id) { final ScheduledFuture<?> sf = map.get(id); return sf!=null && !sf.isDone(); } public static final Pool shutdown() { if(pool == null) return null; Pool p = pool; p.shutdown(); pool = null; map.clear(); return p; } public static final void shutdownWait() { shutdownWait(Task.pool); } public static final void shutdownWait(Pool pool) { if(pool == null) return; if(pool == Task.pool) shutdown(); else pool.shutdown(); if(!pool.isTerminating()) return; try { if(!pool.awaitTermination(Conf.TASK_WAIT_SHUTDOWN, TimeUnit.MILLISECONDS)) { pool.shutdownNow(); pool.awaitTermination(Conf.TASK_WAIT_SHUTDOWN, TimeUnit.MILLISECONDS); } } catch(InterruptedException e) { pool.shutdownNow(); } } public static final void stopAll() { //synchronized(map) { for(ScheduledFuture<?> sf : map.values()) sf.cancel(false); map.clear(); //} } public static final void stop(int id) { //synchronized(map) { final ScheduledFuture<?> sf = map.remove(id); if(sf != null) sf.cancel(false); //} } public static final void stop(int ... ids) { if(pool == null) return; for(int id : ids) stop(id); } }