@Test public void testReschedule() throws InterruptedException { ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(); ran = 0; time = 0; final long EPSILON_NS = 1500000; final int DELAY_MS = 20; final int NUM_OF_ITERATIONS = 8; final int SLEEP_MS = 5; final int AWAIT_SEC = 5; final int EXPECTED_PASS_TIME = NUM_OF_ITERATIONS * SLEEP_MS + (DELAY_MS - SLEEP_MS); final Object tc = this; SingletonTask st1 = new SingletonTask(ses, new Runnable() { @Override public void run() { synchronized (tc) { ran++; } time = System.nanoTime(); } }); long start = System.nanoTime(); for (int i = 0; i < NUM_OF_ITERATIONS; i++) { st1.reschedule(DELAY_MS, TimeUnit.MILLISECONDS); Thread.sleep(SLEEP_MS); assertFalse("Task has run already", ran > 0); } ses.shutdown(); ses.awaitTermination(AWAIT_SEC, TimeUnit.SECONDS); assertEquals("Check that task ran only once failed", 1, ran); assertTrue("Check that time passed appropriately: " + (time - start), (time - start) >= 1000000 * EXPECTED_PASS_TIME - EPSILON_NS); }
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);  }