public SchedulerManager(TaskPriority defaultPriority, long maxWaitForLowPriorityInMs, ThreadFactory threadFactory) { this(new NoThreadScheduler(defaultPriority, maxWaitForLowPriorityInMs), threadFactory); }
@Override public void run() { while (state.get() != 2) { try { scheduler.blockingTick(null); } catch (InterruptedException e) { // reset interrupted status Thread.interrupted(); } catch (Throwable t) { ExceptionUtils.handleException(t); } } } }
/** * Finishes shutdown process, and clears any tasks that remain in the queue. * * @return a list of runnables which remained in the queue after shutdown */ private List<Runnable> finishShutdown() { state.set(2); scheduler.cancelTick(); return scheduler.clearTasks(); }
assertFalse(scheduler.remove(tr)); scheduler.execute(tr); assertTrue(scheduler.remove(tr)); assertFalse(scheduler.remove(tr)); scheduler.submit(tr); assertTrue(scheduler.remove(tr)); assertFalse(scheduler.remove(tr)); scheduler.submit(tr, new Object()); assertTrue(scheduler.remove(tr)); assertFalse(scheduler.remove(tr)); scheduler.schedule(tr, DELAY_TIME); assertTrue(scheduler.remove(tr)); assertFalse(scheduler.remove(tr)); scheduler.submitScheduled(tr, DELAY_TIME); assertTrue(scheduler.remove(tr)); assertFalse(scheduler.remove(tr)); scheduler.submitScheduled(tr, new Object(), DELAY_TIME); assertTrue(scheduler.remove(tr)); assertFalse(scheduler.remove(tr)); scheduler.scheduleWithFixedDelay(tr, 0, DELAY_TIME); assertTrue(scheduler.remove(tr)); assertFalse(scheduler.remove(tr));
@Test public void hasTaskReadyToRunTest() { assertFalse(scheduler.hasTaskReadyToRun()); // schedule in the future scheduler.schedule(DoNothingRunnable.instance(), 1000 * 15); // still should have nothing ready to run assertFalse(scheduler.hasTaskReadyToRun()); scheduler.execute(DoNothingRunnable.instance()); // should now have tasks ready to run assertTrue(scheduler.hasTaskReadyToRun()); scheduler.tick(null); // should no longer have anything to run assertFalse(scheduler.hasTaskReadyToRun()); scheduler.queueManager.highPriorityQueueSet .addScheduled(new OneTimeTaskWrapper(DoNothingRunnable.instance(), scheduler.queueManager.highPriorityQueueSet.scheduleQueue, Clock.lastKnownForwardProgressingMillis())); // now should be true with scheduled task which is ready to run assertTrue(scheduler.hasTaskReadyToRun()); }
@Test public void removeRecurringRunnableTest() throws InterruptedException { TestRunnable immediateRun = new TestRunnable(); TestRunnable initialDelay = new TestRunnable(); assertFalse(scheduler.remove(immediateRun)); scheduler.scheduleWithFixedDelay(immediateRun, 0, DELAY_TIME); assertTrue(scheduler.remove(immediateRun)); scheduler.scheduleWithFixedDelay(immediateRun, 0, DELAY_TIME); scheduler.scheduleWithFixedDelay(initialDelay, DELAY_TIME, DELAY_TIME); assertEquals(1, scheduler.tick(null)); assertEquals(1, immediateRun.getRunCount()); // should have run assertEquals(0, initialDelay.getRunCount()); // should NOT have run yet assertTrue(scheduler.remove(immediateRun)); assertEquals(1, scheduler.blockingTick(null)); assertEquals(1, immediateRun.getRunCount()); // should NOT have run again assertEquals(1, initialDelay.getRunCount()); // should have run }
@Test public void getDelayTillNextTaskRunningTaskTest() { scheduler.execute(new Runnable() { @Override public void run() { assertEquals(Long.MAX_VALUE, scheduler.getDelayTillNextTask()); scheduler.execute(DoNothingRunnable.instance()); assertTrue(scheduler.getDelayTillNextTask() <= 0); scheduler.remove(this); } }); scheduler.tick(null); }
@Test public void hasTaskReadyToRunRunningTaskTest() { scheduler.scheduleWithFixedDelay(new Runnable() { @Override public void run() { assertFalse(scheduler.hasTaskReadyToRun()); scheduler.execute(DoNothingRunnable.instance()); assertTrue(scheduler.hasTaskReadyToRun()); scheduler.remove(this); } }, 0, 1000); scheduler.tick(null); }
@Test public void getDelayTillNextTaskTest() { assertEquals(Long.MAX_VALUE, scheduler.getDelayTillNextTask()); // schedule in the future scheduler.schedule(DoNothingRunnable.instance(), 1000 * 15); // still should have nothing ready to run assertTrue(scheduler.getDelayTillNextTask() > 0); scheduler.execute(DoNothingRunnable.instance()); // should now have tasks ready to run assertTrue(scheduler.getDelayTillNextTask() <= 0); scheduler.tick(null); // should no longer have anything to run assertTrue(scheduler.getDelayTillNextTask() > 0); scheduler.queueManager.highPriorityQueueSet .addScheduled(new OneTimeTaskWrapper(DoNothingRunnable.instance(), scheduler.queueManager.highPriorityQueueSet.scheduleQueue, Clock.lastKnownForwardProgressingMillis())); // now should be true with scheduled task which is ready to run assertTrue(scheduler.getDelayTillNextTask() <= 0); }
@Override public void run() { assertFalse(scheduler.hasTaskReadyToRun()); scheduler.execute(DoNothingRunnable.instance()); assertTrue(scheduler.hasTaskReadyToRun()); scheduler.remove(this); } }, 0, 1000);
@Test public void executeInOrderTest() { TestRunnable lastRun = null; long startTime = System.currentTimeMillis(); int testQty = 0; while (testQty < TEST_QTY || System.currentTimeMillis() - startTime < 100) { testQty++; final TestRunnable fLastRun = lastRun; lastRun = new TestRunnable() { @Override public void handleRunStart() { if (fLastRun != null && !fLastRun.ranOnce()) { fail("last run did not complete"); } } }; scheduler.schedule(DoNothingRunnable.instance(), 5); scheduler.execute(lastRun); } // should throw exception if any internal failures occurred scheduler.tick(null); }
@Test public void clearTasksTest() { scheduler.schedule(DoNothingRunnable.instance(), 1000 * 15); scheduler.execute(DoNothingRunnable.instance()); scheduler.clearTasks(); assertEquals(0, scheduler.queueManager.highPriorityQueueSet.queueSize()); assertEquals(0, scheduler.queueManager.lowPriorityQueueSet.queueSize()); } }
/** * Invoking this will run any tasks which are ready to be run. This will block as it runs as * many scheduled or waiting tasks as possible. It is CRITICAL that only one thread at a time * calls the {@link #tick(ExceptionHandler)} OR {@link #blockingTick(ExceptionHandler)}. While * this class is in general thread safe, if multiple threads invoke either function at the same * time, it is possible a given task may run more than once. In order to maintain high * performance, threadly does not guard against this condition. * <p> * This call allows you to specify an {@link ExceptionHandler}. If provided, if any tasks throw * an exception, this will be called to communicate the exception. This allows you to ensure * that you get a returned task count (meaning if provided, no exceptions will be thrown from * this invocation). If {@code null} is provided for the exception handler, than any tasks * which throw a {@link RuntimeException}, will throw out of this invocation. * <p> * This call is NOT thread safe, calling {@link #tick(ExceptionHandler)} or * {@link #blockingTick(ExceptionHandler)} in parallel could cause the same task to be * run multiple times in parallel. Invoking in parallel will also make the behavior of * {@link #getActiveTaskCount()} non-deterministic and inaccurate. * * @since 3.2.0 * @param exceptionHandler Exception handler implementation to call if any tasks throw an * exception, or null to have exceptions thrown out of this call * @return quantity of tasks run during this tick invocation */ public int tick(ExceptionHandler exceptionHandler) { return tick(exceptionHandler, true); }
@Override public void run() { assertEquals(Long.MAX_VALUE, scheduler.getDelayTillNextTask()); scheduler.execute(DoNothingRunnable.instance()); assertTrue(scheduler.getDelayTillNextTask() <= 0); scheduler.remove(this); } });
@Override public void scheduleAtFixedRate(Runnable task, long initialDelay, long period, TaskPriority priority) { getRunningScheduler().scheduleAtFixedRate(task, initialDelay, period, priority); }
@Override public void scheduleWithFixedDelay(Runnable task, long initialDelay, long recurringDelay, TaskPriority priority) { getRunningScheduler().scheduleWithFixedDelay(task, initialDelay, recurringDelay, priority); }
/** * Start thread for execution if not already started. This can avoid the minor delay of the * thread starting later. * * @param blockTillStarted If {@code true} this will not return till the scheduler thread has started */ public void prestartExecutionThread(boolean blockTillStarted) { if (sManager.startIfNotRunning()) { sManager.scheduler.execute(DoNothingRunnable.instance()); if (blockTillStarted) { while (! sManager.execThread.isAlive() && sManager.state.get() < 1) { Thread.yield(); } } } }
@Test public void removeCallableTest() throws InterruptedException { TestCallable immediateRun = new TestCallable(); TestCallable delayRun = new TestCallable(); assertFalse(scheduler.remove(immediateRun)); scheduler.submitScheduled(immediateRun, 0); assertTrue(scheduler.remove(immediateRun)); assertFalse(scheduler.remove(immediateRun)); scheduler.submitScheduled(delayRun, DELAY_TIME); assertEquals(1, scheduler.blockingTick(null)); assertFalse(immediateRun.isDone()); assertTrue(delayRun.isDone()); }
@Override protected OneTimeTaskWrapper doSchedule(Runnable task, long delayInMillis, TaskPriority priority) { return super.doSchedule(task, delayInMillis, priority); } }
@Test public void submitScheduledRunnableTest() { TestRunnable tr = new TestRunnable(); ListenableFuture<?> future = scheduler.submitScheduled(tr, DELAY_TIME); int runCount = 0; while (runCount == 0) { runCount = scheduler.tick(null); } assertEquals(1, runCount); assertTrue(tr.getDelayTillFirstRun() >= DELAY_TIME); assertTrue(future.isDone()); }