InstantPeriodicTask implements Callable<Void>, Disposable { @Override public void dispose() { Future<?> current = first.getAndSet(CANCELLED); if (current != null && current != CANCELLED) { current.cancel(runner != Thread.currentThread()); } current = rest.getAndSet(CANCELLED); if (current != null && current != CANCELLED) { current.cancel(runner != Thread.currentThread()); } } InstantPeriodicTask(Runnable task, ExecutorService executor); @Override Void call(); @Override void dispose(); @Override boolean isDisposed();  }
@Test public void dispose() throws Exception { ExecutorService exec = Executors.newSingleThreadExecutor(); try { InstantPeriodicTask task = new InstantPeriodicTask(new Runnable() { @Override public void run() { throw new TestException(); } }, exec); assertFalse(task.isDisposed()); task.dispose(); assertTrue(task.isDisposed()); task.dispose(); assertTrue(task.isDisposed()); } finally { exec.shutdownNow(); RxJavaPlugins.reset(); } }