Class PriorityScheduler
- java.lang.Object
-
- org.threadly.concurrent.AbstractSubmitterExecutor
-
- org.threadly.concurrent.AbstractSubmitterScheduler
-
- org.threadly.concurrent.AbstractPriorityScheduler
-
- org.threadly.concurrent.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. UnlikeScheduledThreadPoolExecutor
this scheduled executor's pool size can shrink if set with a lower value viasetPoolSize(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 viaAbstractPriorityScheduler.setMaxWaitForLowPriority(long)
.- Since:
- 2.2.0 (since 1.0.0 as PriorityScheduledExecutor)
-
-
Constructor Summary
Constructors Constructor Description PriorityScheduler(int poolSize)
Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run.PriorityScheduler(int poolSize, boolean useDaemonThreads)
Constructs a new thread pool, though threads will be lazily started as it has tasks ready to run.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.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.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.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.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
adjustPoolSize(int delta)
Adjust the pools size by a given delta.void
awaitTermination()
Block until the thread pool has shutdown and all threads have been stopped.boolean
awaitTermination(long timeoutMillis)
Block until the thread pool has shutdown and all threads have been stopped.int
getActiveTaskCount()
Call to check how many tasks are currently being executed in this thread pool.int
getCurrentPoolSize()
Getter for the current quantity of threads running in this pool (either active or idle).int
getMaxPoolSize()
Getter for the currently set max thread pool size.int
getQueuedTaskCount()
Returns how many tasks are either waiting to be executed, or are scheduled to be executed at a future point.int
getQueuedTaskCount(TaskPriority priority)
Returns a count of how many tasks are either waiting to be executed, or are scheduled to be executed at a future point for a specific priority.boolean
isShutdown()
Function to check if the thread pool is currently accepting and handling tasks.void
prestartAllThreads()
Ensures all threads have been started, it will create threads till the thread count matches the set pool size (checked viagetMaxPoolSize()
).void
scheduleAtFixedRate(java.lang.Runnable task, long initialDelay, long period, TaskPriority priority)
Schedule a fixed rate recurring task to run.void
scheduleWithFixedDelay(java.lang.Runnable task, long initialDelay, long recurringDelay, TaskPriority priority)
Schedule a fixed delay recurring task to run.void
setPoolSize(int newPoolSize)
Change the set thread pool size.void
shutdown()
Stops any new tasks from being submitted to the pool.java.util.List<java.lang.Runnable>
shutdownNow()
Stops any new tasks from being able to be executed and removes workers from the pool.-
Methods inherited from class org.threadly.concurrent.AbstractPriorityScheduler
execute, getDefaultPriority, getMaxWaitForLowPriority, getWaitingForExecutionTaskCount, getWaitingForExecutionTaskCount, remove, remove, schedule, scheduleAtFixedRate, scheduleWithFixedDelay, setMaxWaitForLowPriority, submit, submit, submitScheduled, submitScheduled
-
Methods inherited from class org.threadly.concurrent.AbstractSubmitterScheduler
schedule, submitScheduled, submitScheduled
-
Methods inherited from class org.threadly.concurrent.AbstractSubmitterExecutor
execute, submit, submit
-
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.threadly.concurrent.PrioritySchedulerService
submit, submitScheduled
-
Methods inherited from interface org.threadly.concurrent.SubmitterExecutor
submit, submit, submit
-
Methods inherited from interface org.threadly.concurrent.SubmitterScheduler
schedule, submitScheduled, submitScheduled, submitScheduled
-
-
-
-
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 maintaineduseDaemonThreads
-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 maintaineddefaultPriority
- Default priority for tasks which are submitted without any specified prioritymaxWaitForLowPriorityInMs
- 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 maintaineddefaultPriority
- Default priority for tasks which are submitted without any specified prioritymaxWaitForLowPriorityInMs
- time low priority tasks to wait if there are high priority tasks ready to runuseDaemonThreads
-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 maintaineddefaultPriority
- Default priority for tasks which are submitted without any specified prioritymaxWaitForLowPriorityInMs
- time low priority tasks to wait if there are high priority tasks ready to runthreadFactory
- 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 maintaineddefaultPriority
- Default priority for tasks which are submitted without any specified prioritymaxWaitForLowPriorityInMs
- time low priority tasks to wait if there are high priority tasks ready to runstavableStartsThreads
-true
to have TaskPriority.Starvable tasks start new threadsthreadFactory
- 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 fromgetMaxPoolSize()
in that we lazily create threads. This represents the amount of threads needed to be created so far, wheregetMaxPoolSize()
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 aIllegalStateException
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. UnlikegetCurrentPoolSize()
, 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 viagetMaxPoolSize()
). 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. Ifshutdown()
orshutdownNow()
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 neithershutdown()
orshutdownNow()
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 neithershutdown()
orshutdownNow()
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
-
getQueuedTaskCount
public int getQueuedTaskCount()
Description copied from interface:SchedulerService
Returns how many tasks are either waiting to be executed, or are scheduled to be executed at a future point. This can indicate pool back pressure, but it can also just indicate generally scheduled tasks. It's computationally cheaper thanSchedulerService.getWaitingForExecutionTaskCount()
.- Specified by:
getQueuedTaskCount
in interfaceSchedulerService
- Overrides:
getQueuedTaskCount
in classAbstractPriorityScheduler
- Returns:
- quantity of tasks waiting execution or scheduled to be executed later
-
getQueuedTaskCount
public int getQueuedTaskCount(TaskPriority priority)
Description copied from interface:PrioritySchedulerService
Returns a count of how many tasks are either waiting to be executed, or are scheduled to be executed at a future point for a specific priority. This can indicate pool back pressure, but it can also just indicate generally scheduled tasks. It's computationally cheaper thanPrioritySchedulerService.getWaitingForExecutionTaskCount(TaskPriority)
.- Specified by:
getQueuedTaskCount
in interfacePrioritySchedulerService
- Overrides:
getQueuedTaskCount
in classAbstractPriorityScheduler
- Parameters:
priority
- priority for tasks to be counted- Returns:
- quantity of tasks waiting execution or scheduled to be executed later
-
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 therecurringDelay + 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 executedinitialDelay
- delay in milliseconds until first runrecurringDelay
- delay in milliseconds for running task after last finishpriority
- 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 executedinitialDelay
- delay in milliseconds until first runperiod
- amount of time in milliseconds between the start of recurring executionspriority
- priority for task to get available thread to run on
-
-