Class KeyedSubmitterSchedulerLimiter
- java.lang.Object
-
- org.threadly.concurrent.wrapper.limiter.KeyedSubmitterSchedulerLimiter
-
public class KeyedSubmitterSchedulerLimiter extends java.lang.Object
This is a cross between theKeyDistributedScheduler
and aSubmitterSchedulerLimiter
. This is designed to limit concurrency for a given thread, but permit more than one thread to run at a time for a given key. If the desired effect is to have a single thread per key,KeyDistributedScheduler
is a much better option.The easiest way to use this class would be to have it distribute out schedulers through
getSubmitterSchedulerForKey(Object)
.- Since:
- 4.6.0 (since 4.3.0 at org.threadly.concurrent.limiter)
-
-
Constructor Summary
Constructors Constructor Description KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency)
Construct a newKeyedSubmitterSchedulerLimiter
providing only the backing scheduler and the maximum concurrency per unique key.KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency, boolean limitFutureListenersExecution)
Construct a newKeyedSubmitterSchedulerLimiter
providing only the backing scheduler and the maximum concurrency per unique key.KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency, java.lang.String subPoolName, boolean addKeyToThreadName)
Construct a newKeyedSubmitterSchedulerLimiter
providing the backing scheduler, the maximum concurrency per unique key, and how keyed limiter threads should be named.KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency, java.lang.String subPoolName, boolean addKeyToThreadName, boolean limitFutureListenersExecution)
Construct a newKeyedSubmitterSchedulerLimiter
providing the backing scheduler, the maximum concurrency per unique key, and how keyed limiter threads should be named.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
execute(java.lang.Object taskKey, java.lang.Runnable task)
Provide a task to be run with a given thread key.int
getMaxConcurrencyPerKey()
Check how many threads may run in parallel for a single unique key.SubmitterExecutor
getSubmitterExecutorForKey(java.lang.Object taskKey)
Returns an executor implementation where all tasks submitted on this executor will run on the provided key.SubmitterScheduler
getSubmitterSchedulerForKey(java.lang.Object taskKey)
Returns a scheduler implementation where all tasks submitted on this scheduler will run on the provided key.int
getTrackedKeyCount()
Check how many keys are currently being restricted or monitored.int
getUnsubmittedTaskCount(java.lang.Object taskKey)
Check how many tasks are currently being limited, and not submitted yet for a given key.java.util.Map<java.lang.Object,java.lang.Integer>
getUnsubmittedTaskCountMap()
Get a map of all the keys and how many tasks are held back (queued) in each limiter per key.void
schedule(java.lang.Object taskKey, java.lang.Runnable task, long delayInMs)
Schedule a one time task with a given delay.void
scheduleAtFixedRate(java.lang.Object taskKey, java.lang.Runnable task, long initialDelay, long period)
Schedule a fixed rate recurring task to run.void
scheduleWithFixedDelay(java.lang.Object taskKey, java.lang.Runnable task, long initialDelay, long recurringDelay)
Schedule a fixed delay recurring task to run.void
setMaxConcurrencyPerKey(int maxConcurrency)
Updates the concurrency limit for each key.ListenableFuture<?>
submit(java.lang.Object taskKey, java.lang.Runnable task)
Submit a task to be run with a given thread key.<TT> ListenableFuture<TT>
submit(java.lang.Object taskKey, java.lang.Runnable task, TT result)
Submit a task to be run with a given thread key.<TT> ListenableFuture<TT>
submit(java.lang.Object taskKey, java.util.concurrent.Callable<TT> task)
Submit a callable to be run with a given thread key.ListenableFuture<?>
submitScheduled(java.lang.Object taskKey, java.lang.Runnable task, long delayInMs)
Schedule a task with a given delay.<TT> ListenableFuture<TT>
submitScheduled(java.lang.Object taskKey, java.lang.Runnable task, TT result, long delayInMs)
Schedule a task with a given delay.<TT> ListenableFuture<TT>
submitScheduled(java.lang.Object taskKey, java.util.concurrent.Callable<TT> task, long delayInMs)
Schedule aCallable
with a given delay.
-
-
-
Constructor Detail
-
KeyedSubmitterSchedulerLimiter
public KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency)
Construct a newKeyedSubmitterSchedulerLimiter
providing only the backing scheduler and the maximum concurrency per unique key. By default this will not rename threads for tasks executing.- Parameters:
scheduler
- Scheduler to execute and schedule tasks onmaxConcurrency
- Maximum concurrency allowed per task key
-
KeyedSubmitterSchedulerLimiter
public KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency, boolean limitFutureListenersExecution)
Construct a newKeyedSubmitterSchedulerLimiter
providing only the backing scheduler and the maximum concurrency per unique key. By default this will not rename threads for tasks executing.This constructor allows you to specify if listeners /
FutureCallback
's / functions inListenableFuture.map(java.util.function.Function)
orListenableFuture.flatMap(java.util.function.Function)
should be counted towards the concurrency limit. Specifyingfalse
will release the limit as soon as the original task completes. Specifyingtrue
will continue to enforce the limit until all listeners (without an executor) complete.- Parameters:
scheduler
- Scheduler to execute and schedule tasks onmaxConcurrency
- Maximum concurrency allowed per task keylimitFutureListenersExecution
-true
to include listener / mapped functions towards execution limit
-
KeyedSubmitterSchedulerLimiter
public KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency, java.lang.String subPoolName, boolean addKeyToThreadName)
Construct a newKeyedSubmitterSchedulerLimiter
providing the backing scheduler, the maximum concurrency per unique key, and how keyed limiter threads should be named.- Parameters:
scheduler
- Scheduler to execute and schedule tasks onmaxConcurrency
- Maximum concurrency allowed per task keysubPoolName
- Name prefix for sub pools,null
to not change thread namesaddKeyToThreadName
- Iftrue
the key's .toString() will be added in the thread name
-
KeyedSubmitterSchedulerLimiter
public KeyedSubmitterSchedulerLimiter(SubmitterScheduler scheduler, int maxConcurrency, java.lang.String subPoolName, boolean addKeyToThreadName, boolean limitFutureListenersExecution)
Construct a newKeyedSubmitterSchedulerLimiter
providing the backing scheduler, the maximum concurrency per unique key, and how keyed limiter threads should be named.This constructor allows you to specify if listeners /
FutureCallback
's / functions inListenableFuture.map(java.util.function.Function)
orListenableFuture.flatMap(java.util.function.Function)
should be counted towards the concurrency limit. Specifyingfalse
will release the limit as soon as the original task completes. Specifyingtrue
will continue to enforce the limit until all listeners (without an executor) complete.- Parameters:
scheduler
- Scheduler to execute and schedule tasks onmaxConcurrency
- Maximum concurrency allowed per task keysubPoolName
- Name prefix for sub pools,null
to not change thread namesaddKeyToThreadName
- Iftrue
the key's .toString() will be added in the thread namelimitFutureListenersExecution
-true
to include listener / mapped functions towards execution limit
-
-
Method Detail
-
submitScheduled
public ListenableFuture<?> submitScheduled(java.lang.Object taskKey, java.lang.Runnable task, long delayInMs)
Schedule a task with a given delay. There is a slight increase in load when usingsubmitScheduled(Object, Runnable, long)
overschedule(Object, Runnable, long)
. So this should only be used when the future is necessary.The
Future.get()
method will returnnull
once the runnable has completed.The key is used to identify this threads execution limit. Tasks with matching keys will be limited concurrent execution to the level returned by
getMaxConcurrencyPerKey()
.See also:
SubmitterScheduler.submitScheduled(Runnable, long)
- Parameters:
taskKey
- Key to use for identifying execution limittask
- runnable to executedelayInMs
- time in milliseconds to wait to execute task- Returns:
- a future to know when the task has completed
-
submitScheduled
public <TT> ListenableFuture<TT> submitScheduled(java.lang.Object taskKey, java.lang.Runnable task, TT result, long delayInMs)
Schedule a task with a given delay. TheFuture.get()
method will return the provided result once the runnable has completed.The key is used to identify this threads execution limit. Tasks with matching keys will be limited concurrent execution to the level returned by
getMaxConcurrencyPerKey()
.See also:
SubmitterScheduler.submitScheduled(Runnable, Object, long)
- Type Parameters:
TT
- type of result returned from the future- Parameters:
taskKey
- Key to use for identifying execution limittask
- runnable to executeresult
- result to be returned from resulting future .get() when runnable completesdelayInMs
- time in milliseconds to wait to execute task- Returns:
- a future to know when the task has completed
-
submitScheduled
public <TT> ListenableFuture<TT> submitScheduled(java.lang.Object taskKey, java.util.concurrent.Callable<TT> task, long delayInMs)
Schedule aCallable
with a given delay. This is needed when a result needs to be consumed from the callable.The key is used to identify this threads execution limit. Tasks with matching keys will be limited concurrent execution to the level returned by
getMaxConcurrencyPerKey()
.See also:
SubmitterScheduler.submitScheduled(Callable, long)
- Type Parameters:
TT
- type of result returned from the future- Parameters:
taskKey
- Key to use for identifying execution limittask
- callable to be executeddelayInMs
- time in milliseconds to wait to execute task- Returns:
- a future to know when the task has completed and get the result of the callable
-
schedule
public void schedule(java.lang.Object taskKey, java.lang.Runnable task, long delayInMs)
Schedule a one time task with a given delay.The key is used to identify this threads execution limit. Tasks with matching keys will be limited concurrent execution to the level returned by
getMaxConcurrencyPerKey()
.- Parameters:
taskKey
- Key to use for identifying execution limittask
- runnable to executedelayInMs
- time in milliseconds to wait to execute task
-
scheduleWithFixedDelay
public void scheduleWithFixedDelay(java.lang.Object taskKey, java.lang.Runnable task, long initialDelay, long recurringDelay)
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).The key is used to identify this threads execution limit. Tasks with matching keys will be limited concurrent execution to the level returned by
getMaxConcurrencyPerKey()
.See also:
SubmitterScheduler.scheduleWithFixedDelay(Runnable, long, long)
- Parameters:
taskKey
- Key to use for identifying execution limittask
- runnable to be executedinitialDelay
- delay in milliseconds until first runrecurringDelay
- delay in milliseconds for running task after last finish
-
scheduleAtFixedRate
public void scheduleAtFixedRate(java.lang.Object taskKey, java.lang.Runnable task, long initialDelay, long period)
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).The key is used to identify this threads execution limit. Tasks with matching keys will be limited concurrent execution to the level returned by
getMaxConcurrencyPerKey()
.See also:
SubmitterScheduler.scheduleAtFixedRate(Runnable, long, long)
- Parameters:
taskKey
- Key to use for identifying execution limittask
- runnable to be executedinitialDelay
- delay in milliseconds until first runperiod
- amount of time in milliseconds between the start of recurring executions
-
getSubmitterSchedulerForKey
public SubmitterScheduler getSubmitterSchedulerForKey(java.lang.Object taskKey)
Returns a scheduler implementation where all tasks submitted on this scheduler will run on the provided key. Tasks executed on the returned scheduler will be limited by the key submitted on this instance equally with ones provided through the returned instance.- Parameters:
taskKey
- object key whereequals()
will be used to determine execution thread- Returns:
- scheduler which will only execute with reference to the provided key
-
getMaxConcurrencyPerKey
public int getMaxConcurrencyPerKey()
Check how many threads may run in parallel for a single unique key.- Returns:
- maximum concurrent tasks to be run per key
-
setMaxConcurrencyPerKey
public void setMaxConcurrencyPerKey(int maxConcurrency)
Updates the concurrency limit for each key. If reducing the the limit, there will be no attempt or impact on tasks already limiting. Instead new tasks just wont be submitted to the parent pool until existing tasks complete and go below the new limit.- Parameters:
maxConcurrency
- maximum quantity of tasks to run in parallel per key- Since:
- 5.4
-
getTrackedKeyCount
public int getTrackedKeyCount()
Check how many keys are currently being restricted or monitored.- Returns:
- The number of task keys being monitored
-
getUnsubmittedTaskCount
public int getUnsubmittedTaskCount(java.lang.Object taskKey)
Check how many tasks are currently being limited, and not submitted yet for a given key. This can be useful for knowing how backed up a specific key is.- Parameters:
taskKey
- Key which would be limited- Returns:
- Quantity of tasks being held back inside the limiter, and thus still queued
-
getUnsubmittedTaskCountMap
public java.util.Map<java.lang.Object,java.lang.Integer> getUnsubmittedTaskCountMap()
Get a map of all the keys and how many tasks are held back (queued) in each limiter per key. This map is generated without locking. Due to that, this may be inaccurate as task queue sizes changed while iterating all key's limiters.Because this requires an iteration of all limiters, if only a single limiters unsubmitted count is needed, use
getUnsubmittedTaskCount(Object)
as a cheaper alternative.- Returns:
- Map of task key's to their respective task queue size
-
execute
public void execute(java.lang.Object taskKey, java.lang.Runnable task)
Provide a task to be run with a given thread key.See also:
Executor.execute(Runnable)
- Parameters:
taskKey
- object key whereequals()
will be used to determine execution threadtask
- Task to be executed
-
submit
public ListenableFuture<?> submit(java.lang.Object taskKey, java.lang.Runnable task)
Submit a task to be run with a given thread key.See also:
SubmitterExecutor.submit(Runnable)
- Parameters:
taskKey
- object key whereequals()
will be used to determine execution threadtask
- Task to be executed- Returns:
- Future to represent when the execution has occurred
-
submit
public <TT> ListenableFuture<TT> submit(java.lang.Object taskKey, java.lang.Runnable task, TT result)
Submit a task to be run with a given thread key.- Type Parameters:
TT
- type of result returned from the future- Parameters:
taskKey
- object key whereequals()
will be used to determine execution threadtask
- Runnable to be executedresult
- Result to be returned from future when task completes- Returns:
- Future to represent when the execution has occurred and provide the given result
-
submit
public <TT> ListenableFuture<TT> submit(java.lang.Object taskKey, java.util.concurrent.Callable<TT> task)
Submit a callable to be run with a given thread key.See also:
SubmitterExecutor.submit(Callable)
- Type Parameters:
TT
- type of result returned from the future- Parameters:
taskKey
- object key whereequals()
will be used to determine execution threadtask
- Callable to be executed- Returns:
- Future to represent when the execution has occurred and provide the result from the callable
-
getSubmitterExecutorForKey
public SubmitterExecutor getSubmitterExecutorForKey(java.lang.Object taskKey)
Returns an executor implementation where all tasks submitted on this executor will run on the provided key. Tasks executed on the returned scheduler will be limited by the key submitted on this instance equally with ones provided through the returned instance.- Parameters:
taskKey
- object key whereequals()
will be used to determine execution thread- Returns:
- Executor which will only execute with reference to the provided key
-
-