Class PriorityScheduler

  • All Implemented Interfaces:
    java.util.concurrent.Executor, PrioritySchedulerService, SchedulerService, SubmitterExecutor, SubmitterScheduler
    Direct Known Subclasses:
    PrioritySchedulerStatisticTracker

    public class PriorityScheduler
    extends AbstractPriorityScheduler
    Executor to run tasks, schedule tasks. Unlike ScheduledThreadPoolExecutor this scheduled executor's pool size can shrink if set with a lower value via setPoolSize(int). It also has the benefit that you can provide "low priority" tasks.

    These low priority tasks will delay their execution if there are other high priority tasks ready to run, as long as they have not exceeded their maximum wait time. If they have exceeded their maximum wait time, and high priority tasks delay time is less than the low priority delay time, then those low priority tasks will be executed. What this results in is a task which has lower priority, but which wont be starved from execution.

    Most tasks provided into this pool will likely want to be "high priority", to more closely match the behavior of other thread pools. That is why unless specified by the constructor, the default TaskPriority is High.

    In all conditions, "low priority" tasks will never be starved. This makes "low priority" tasks ideal which do regular cleanup, or in general anything that must run, but cares little if there is a 1, or 10 second gap in the execution time. That amount of tolerance is adjustable by setting the maxWaitForLowPriorityInMs either in the constructor, or at runtime via AbstractPriorityScheduler.setMaxWaitForLowPriority(long).

    Since:
    2.2.0 (since 1.0.0 as PriorityScheduledExecutor)
    • Constructor Detail

      • PriorityScheduler

        public PriorityScheduler​(int poolSize)
        Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run. This constructs a default priority of high (which makes sense for most use cases). It also defaults low priority task wait as 500ms. It also defaults to all newly created threads to being daemon threads.
        Parameters:
        poolSize - Thread pool size that should be maintained
      • PriorityScheduler

        public PriorityScheduler​(int poolSize,
                                 boolean useDaemonThreads)
        Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run. This constructs a default priority of high (which makes sense for most use cases). It also defaults low priority task wait as 500ms.
        Parameters:
        poolSize - Thread pool size that should be maintained
        useDaemonThreads - true if newly created threads should be daemon
      • PriorityScheduler

        public PriorityScheduler​(int poolSize,
                                 TaskPriority defaultPriority,
                                 long maxWaitForLowPriorityInMs)
        Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run. This provides the extra parameters to tune what tasks submitted without a priority will be scheduled as. As well as the maximum wait for low priority tasks.
        Parameters:
        poolSize - Thread pool size that should be maintained
        defaultPriority - Default priority for tasks which are submitted without any specified priority
        maxWaitForLowPriorityInMs - time low priority tasks to wait if there are high priority tasks ready to run
      • PriorityScheduler

        public PriorityScheduler​(int poolSize,
                                 TaskPriority defaultPriority,
                                 long maxWaitForLowPriorityInMs,
                                 boolean useDaemonThreads)
        Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run. This provides the extra parameters to tune what tasks submitted without a priority will be scheduled as. As well as the maximum wait for low priority tasks.
        Parameters:
        poolSize - Thread pool size that should be maintained
        defaultPriority - Default priority for tasks which are submitted without any specified priority
        maxWaitForLowPriorityInMs - time low priority tasks to wait if there are high priority tasks ready to run
        useDaemonThreads - true if newly created threads should be daemon
      • PriorityScheduler

        public PriorityScheduler​(int poolSize,
                                 TaskPriority defaultPriority,
                                 long maxWaitForLowPriorityInMs,
                                 java.util.concurrent.ThreadFactory threadFactory)
        Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run. This provides the extra parameters to tune what tasks submitted without a priority will be scheduled as. As well as the maximum wait for low priority tasks.
        Parameters:
        poolSize - Thread pool size that should be maintained
        defaultPriority - Default priority for tasks which are submitted without any specified priority
        maxWaitForLowPriorityInMs - time low priority tasks to wait if there are high priority tasks ready to run
        threadFactory - thread factory for producing new threads within executor
      • PriorityScheduler

        public PriorityScheduler​(int poolSize,
                                 TaskPriority defaultPriority,
                                 long maxWaitForLowPriorityInMs,
                                 boolean stavableStartsThreads,
                                 java.util.concurrent.ThreadFactory threadFactory)
        Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run. This provides the extra parameters to tune what tasks submitted without a priority will be scheduled as. As well as the maximum wait for low priority tasks.
        Parameters:
        poolSize - Thread pool size that should be maintained
        defaultPriority - Default priority for tasks which are submitted without any specified priority
        maxWaitForLowPriorityInMs - time low priority tasks to wait if there are high priority tasks ready to run
        stavableStartsThreads - true to have TaskPriority.Starvable tasks start new threads
        threadFactory - thread factory for producing new threads within executor
    • Method Detail

      • getMaxPoolSize

        public int getMaxPoolSize()
        Getter for the currently set max thread pool size.
        Returns:
        current max pool size
      • getCurrentPoolSize

        public int getCurrentPoolSize()
        Getter for the current quantity of threads running in this pool (either active or idle). This is different than the size returned from getMaxPoolSize() in that we lazily create threads. This represents the amount of threads needed to be created so far, where getMaxPoolSize() represents the amount of threads the pool may grow to.
        Returns:
        current thread count
      • setPoolSize

        public void setPoolSize​(int newPoolSize)
        Change the set thread pool size.

        If the value is less than the current running threads, as threads finish they will exit rather than accept new tasks. No currently running tasks will be interrupted, rather we will just wait for them to finish before killing the thread.

        If this is an increase in the pool size, threads will be lazily started as needed till the new size is reached. If there are tasks waiting for threads to run on, they immediately will be started.

        Parameters:
        newPoolSize - New core pool size, must be at least one
      • adjustPoolSize

        public void adjustPoolSize​(int delta)
        Adjust the pools size by a given delta. If the provided delta would result in a pool size of zero or less, then a IllegalStateException will be thrown.
        Parameters:
        delta - Delta to adjust the max pool size by
      • getActiveTaskCount

        public int getActiveTaskCount()
        Call to check how many tasks are currently being executed in this thread pool. Unlike getCurrentPoolSize(), this count will NOT include idle threads waiting to execute tasks.
        Returns:
        current number of running tasks
      • prestartAllThreads

        public void prestartAllThreads()
        Ensures all threads have been started, it will create threads till the thread count matches the set pool size (checked via getMaxPoolSize()). These new threads will remain idle till there is tasks ready to execute.
      • isShutdown

        public boolean isShutdown()
        Description copied from interface: SchedulerService
        Function to check if the thread pool is currently accepting and handling tasks.
        Returns:
        true if thread pool is running
      • shutdown

        public void shutdown()
        Stops any new tasks from being submitted to the pool. But allows all tasks which are submitted to execute, or scheduled (and have elapsed their delay time) to run. If recurring tasks are present they will also be unable to reschedule. If shutdown() or shutdownNow() has already been called, this will have no effect.

        If you wish to not want to run any queued tasks you should use shutdownNow().

      • shutdownNow

        public java.util.List<java.lang.Runnable> shutdownNow()
        Stops any new tasks from being able to be executed and removes workers from the pool.

        This implementation refuses new submissions after this call. And will NOT interrupt any tasks which are currently running. However any tasks which are waiting in queue to be run (but have not started yet), will not be run. Those waiting tasks will be removed, and as workers finish with their current tasks the threads will be joined.

        Returns:
        List of runnables which were waiting to execute
      • awaitTermination

        public void awaitTermination()
                              throws java.lang.InterruptedException
        Block until the thread pool has shutdown and all threads have been stopped. If neither shutdown() or shutdownNow() is invoked, then this will block forever.
        Throws:
        java.lang.InterruptedException - Thrown if blocking thread is interrupted waiting for shutdown
      • awaitTermination

        public boolean awaitTermination​(long timeoutMillis)
                                 throws java.lang.InterruptedException
        Block until the thread pool has shutdown and all threads have been stopped. If neither shutdown() or shutdownNow() is invoked, then this will block until the timeout is reached.
        Parameters:
        timeoutMillis - time to block and wait for thread pool to shutdown
        Returns:
        true if the pool has shutdown, false if timeout was reached
        Throws:
        java.lang.InterruptedException - Thrown if blocking thread is interrupted waiting for shutdown
      • scheduleWithFixedDelay

        public void scheduleWithFixedDelay​(java.lang.Runnable task,
                                           long initialDelay,
                                           long recurringDelay,
                                           TaskPriority priority)
        Description copied from interface: PrioritySchedulerService
        Schedule a fixed delay recurring task to run. The recurring delay time will be from the point where execution has finished. So the execution frequency is the recurringDelay + runtime for the provided task.

        Unlike ScheduledExecutorService if the task throws an exception, subsequent executions are NOT suppressed or prevented. So if the task throws an exception on every run, the task will continue to be executed at the provided recurring delay (possibly throwing an exception on each execution).

        Parameters:
        task - runnable to be executed
        initialDelay - delay in milliseconds until first run
        recurringDelay - delay in milliseconds for running task after last finish
        priority - priority for task to get available thread to run on
      • scheduleAtFixedRate

        public void scheduleAtFixedRate​(java.lang.Runnable task,
                                        long initialDelay,
                                        long period,
                                        TaskPriority priority)
        Description copied from interface: PrioritySchedulerService
        Schedule a fixed rate recurring task to run. The recurring delay will be the same, regardless of how long task execution takes. A given runnable will not run concurrently (unless it is submitted to the scheduler multiple times). Instead of execution takes longer than the period, the next run will occur immediately (given thread availability in the pool).

        Unlike ScheduledExecutorService if the task throws an exception, subsequent executions are NOT suppressed or prevented. So if the task throws an exception on every run, the task will continue to be executed at the provided recurring delay (possibly throwing an exception on each execution).

        Parameters:
        task - runnable to be executed
        initialDelay - delay in milliseconds until first run
        period - amount of time in milliseconds between the start of recurring executions
        priority - priority for task to get available thread to run on