@Test public void testReschedule() throws InterruptedException { ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(); final Object tc = this; SingletonTask st1 = new SingletonTask(ses, new Runnable() { @Override public void run() { synchronized (tc) { ran += 1; } time = System.nanoTime(); } }); long start = System.nanoTime(); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); st1.reschedule(20, TimeUnit.MILLISECONDS); Thread.sleep(5); assertFalse("Check that task hasn't run yet", ran > 0); ses.shutdown(); ses.awaitTermination(5, TimeUnit.SECONDS); assertEquals("Check that task ran only once", 1, ran); assertTrue("Check that time passed appropriately: " + (time - start), (time - start) >= TimeUnit.NANOSECONDS.convert(55, TimeUnit.MILLISECONDS)); }
public void reschedule(long delay, TimeUnit unit) { boolean needQueue = true; SingletonTaskWorker stw = null; synchronized (context) { if (context.taskRunning || context.taskShouldRun) { if (context.taskRunning) { if (delay > 0) { long now = System.nanoTime(); long then = now + TimeUnit.NANOSECONDS.convert(delay, unit); context.waitingTask.nextschedule = then; } else { context.waitingTask.nextschedule = 0; } needQueue = false; } else { context.waitingTask.canceled = true; context.waitingTask = null; } } context.taskShouldRun = true; if (needQueue) { stw = context.waitingTask = new SingletonTaskWorker(this); } } if (needQueue) { if (delay <= 0) ses.execute(stw); else ses.schedule(stw, delay, unit); } }
SingletonTask { public void reschedule(long delay, TimeUnit unit) { boolean needQueue = true; SingletonTaskWorker stw = null; synchronized (context) { if (context.taskRunning || context.taskShouldRun) { if (context.taskRunning) { if (delay > 0) { long now = System.nanoTime(); long then = now + TimeUnit.NANOSECONDS.convert(delay, unit); context.waitingTask.nextschedule = then; } else { context.waitingTask.nextschedule = 0; } needQueue = false; } else { context.waitingTask.canceled = true; context.waitingTask = null; } } context.taskShouldRun = true; if (needQueue) { stw = context.waitingTask = new SingletonTaskWorker(this); } } if (needQueue) { if (delay <= 0) ses.execute(stw); else ses.schedule(stw, delay, unit); } } }
SingletonTask { public void reschedule(long delay, TimeUnit unit) { boolean needQueue = true; SingletonTaskWorker stw = null; synchronized (context) { if (context.taskRunning || context.taskShouldRun) { if (context.taskRunning) { if (delay > 0) { long now = System.nanoTime(); long then = now + TimeUnit.NANOSECONDS.convert(delay, unit); context.waitingTask.nextschedule = then; } else { context.waitingTask.nextschedule = 0; } needQueue = false; } else { context.waitingTask.canceled = true; context.waitingTask = null; } } context.taskShouldRun = true; if (needQueue) { stw = context.waitingTask = new SingletonTaskWorker(this); } } if (needQueue) { if (delay <= 0) ses.execute(stw); else ses.schedule(stw, delay, unit); } } SingletonTask(ScheduledExecutorService ses,
            Runnable task); }
SingletonTask { public void reschedule(long delay, TimeUnit unit) { boolean needQueue = true; SingletonTaskWorker stw = null; synchronized (context) { if (context.taskRunning || context.taskShouldRun) { if (context.taskRunning) { if (delay > 0) { long now = System.nanoTime(); long then = now + TimeUnit.NANOSECONDS.convert(delay, unit); context.waitingTask.nextschedule = then; } else { context.waitingTask.nextschedule = 0; } needQueue = false; } else { context.waitingTask.canceled = true; context.waitingTask = null; } } context.taskShouldRun = true; if (needQueue) { stw = context.waitingTask = new SingletonTaskWorker(this); } } if (needQueue) { if (delay <= 0) ses.execute(stw); else ses.schedule(stw, delay, unit); } } SingletonTask(ScheduledExecutorService ses,
            Runnable task); void reschedule(long delay, TimeUnit unit); }
SingletonTask { public void reschedule(long delay, TimeUnit unit) { boolean needQueue = true; SingletonTaskWorker stw = null; synchronized (context) { if (context.taskRunning || context.taskShouldRun) { if (context.taskRunning) { if (delay > 0) { long now = System.nanoTime(); long then = now + TimeUnit.NANOSECONDS.convert(delay, unit); context.waitingTask.nextschedule = then; } else { context.waitingTask.nextschedule = 0; } needQueue = false; } else { context.waitingTask.canceled = true; context.waitingTask = null; } } context.taskShouldRun = true; if (needQueue) { stw = context.waitingTask = new SingletonTaskWorker(this); } } if (needQueue) { if (delay <= 0) ses.execute(stw); else ses.schedule(stw, delay, unit); } } SingletonTask(ScheduledExecutorService ses,
            Runnable task); void reschedule(long delay, TimeUnit unit);  }