public class KeyDistributedExecutor
extends java.lang.Object
Because of that, it is recommended that the executor provided has as many possible threads as possible keys that could be provided to be run in parallel. If this class is starved for threads some keys may continue to process new tasks, while other keys could be starved.
Assuming that the shared memory (any objects, primitives, etc) are only accessed through the
same instance of KeyDistributedExecutor
, and assuming that those variables are only
accessed via the same key. Then the programmer does not need to worry about synchronization, or
volatile. The KeyDistributedExecutor
will ensure the happens-before relationship.
Constructor and Description |
---|
KeyDistributedExecutor(java.util.concurrent.Executor executor)
Constructor to use a provided executor implementation for running tasks.
|
KeyDistributedExecutor(java.util.concurrent.Executor executor,
boolean accurateQueueSize)
Constructor to use a provided executor implementation for running tasks.
|
KeyDistributedExecutor(java.util.concurrent.Executor executor,
int maxTasksPerCycle)
Constructor to use a provided executor implementation for running tasks.
|
KeyDistributedExecutor(java.util.concurrent.Executor executor,
int maxTasksPerCycle,
boolean accurateQueueSize)
Constructor to use a provided executor implementation for running tasks.
|
Modifier and Type | Method and Description |
---|---|
void |
execute(java.lang.Object threadKey,
java.lang.Runnable task)
Provide a task to be run with a given thread key.
|
java.util.concurrent.Executor |
getExecutor()
Getter for the executor being used behind the scenes.
|
SubmitterExecutor |
getExecutorForKey(java.lang.Object threadKey)
Returns a
SubmitterExecutor implementation where all tasks submitted on this executor
will run on the provided key. |
int |
getTaskQueueSize(java.lang.Object threadKey)
Call to check how many tasks have been queued up for a given key.
|
java.util.Map<java.lang.Object,java.lang.Integer> |
getTaskQueueSizeMap()
Get a map of all the keys and how many tasks are queued per key.
|
<T> ListenableFuture<T> |
submit(java.lang.Object threadKey,
java.util.concurrent.Callable<T> task)
Submit a callable to be run with a given thread key.
|
ListenableFuture<?> |
submit(java.lang.Object threadKey,
java.lang.Runnable task)
Submit a task to be run with a given thread key.
|
<T> ListenableFuture<T> |
submit(java.lang.Object threadKey,
java.lang.Runnable task,
T result)
Submit a task to be run with a given thread key.
|
public KeyDistributedExecutor(java.util.concurrent.Executor executor)
This constructs with a default expected level of concurrency of 16. This also does not
attempt to have an accurate queue size for the getTaskQueueSize(Object)
call (thus
preferring high performance).
executor
- A multi-threaded executor to distribute tasks to. Ideally has as many
possible threads as keys that will be used in parallel.public KeyDistributedExecutor(java.util.concurrent.Executor executor, boolean accurateQueueSize)
This constructor allows you to specify if you want accurate queue sizes to be tracked for
given thread keys. There is a performance hit associated with this, so this should only be
enabled if getTaskQueueSize(Object)
calls will be used.
This constructs with a default expected level of concurrency of 16.
executor
- A multi-threaded executor to distribute tasks to. Ideally has as many
possible threads as keys that will be used in parallel.accurateQueueSize
- true
to make getTaskQueueSize(Object)
more accuratepublic KeyDistributedExecutor(java.util.concurrent.Executor executor, int maxTasksPerCycle)
This constructor allows you to provide a maximum number of tasks for a key before it yields to another key. This can make it more fair, and make it so no single key can starve other keys from running. The lower this is set however, the less efficient it becomes in part because it has to give up the thread and get it again, but also because it must copy the subset of the task queue which it can run.
This also allows you to specify if you want accurate queue sizes to be tracked for given
thread keys. There is a performance hit associated with this, so this should only be enabled
if getTaskQueueSize(Object)
calls will be used.
This constructs with a default expected level of concurrency of 16. This also does not attempt to have an accurate queue size for the "getTaskQueueSize" call (thus preferring high performance).
executor
- A multi-threaded executor to distribute tasks to. Ideally has as many
possible threads as keys that will be used in parallel.maxTasksPerCycle
- maximum tasks run per key before yielding for other keyspublic KeyDistributedExecutor(java.util.concurrent.Executor executor, int maxTasksPerCycle, boolean accurateQueueSize)
This constructor allows you to provide a maximum number of tasks for a key before it yields to another key. This can make it more fair, and make it so no single key can starve other keys from running. The lower this is set however, the less efficient it becomes in part because it has to give up the thread and get it again, but also because it must copy the subset of the task queue which it can run.
This also allows you to specify if you want accurate queue sizes to be tracked for given
thread keys. There is a performance hit associated with this, so this should only be enabled
if getTaskQueueSize(Object)
calls will be used.
This constructs with a default expected level of concurrency of 16.
executor
- A multi-threaded executor to distribute tasks to. Ideally has as many
possible threads as keys that will be used in parallel.maxTasksPerCycle
- maximum tasks run per key before yielding for other keysaccurateQueueSize
- true
to make getTaskQueueSize(Object)
more accuratepublic java.util.concurrent.Executor getExecutor()
public SubmitterExecutor getExecutorForKey(java.lang.Object threadKey)
SubmitterExecutor
implementation where all tasks submitted on this executor
will run on the provided key.threadKey
- object key where hashCode will be used to determine execution threadpublic int getTaskQueueSize(java.lang.Object threadKey)
true
was passed in for accurateQueueSize
, the
accuracy of this call varies dramatically.
If true
was not supplied in the constructor for accurateQueueSize
, this will
only report how many tasks have not been accepted by the worker yet. The accepting of those
tasks occur in batches, so this number will vary dramatically (and probably be unusable).
So it is highly recommended that if your interested in this functionality you supply a
true
into the constructor.
Supplying a true
for accurateQueueSize
in the constructor does involve some
performance cost, but that overhead should be minimal (just no reason to accept any loss if
not interested in this feature).
threadKey
- key for task queue to examinepublic java.util.Map<java.lang.Object,java.lang.Integer> getTaskQueueSizeMap()
Because this requires an iteration of all task workers, if only a single key's queue size is
needed, use getTaskQueueSize(Object)
as a cheaper alternative.
If true
was not supplied in the constructor for accurateQueueSize
, this will
only report how many tasks have not been accepted by the worker yet. The accepting of those
tasks occur in batches, so this number will vary dramatically (and probably be unusable).
So it is highly recommended that if your interested in this functionality you supply a
true
into the constructor.
Supplying a true
for accurateQueueSize
in the constructor does involve some
performance cost, but that overhead should be minimal (just no reason to accept any loss if
not interested in this feature).
public void execute(java.lang.Object threadKey, java.lang.Runnable task)
threadKey
- object key where equals()
will be used to determine execution threadtask
- Task to be executedpublic ListenableFuture<?> submit(java.lang.Object threadKey, java.lang.Runnable task)
threadKey
- object key where equals()
will be used to determine execution threadtask
- Task to be executedpublic <T> ListenableFuture<T> submit(java.lang.Object threadKey, java.lang.Runnable task, T result)
T
- type of result returned from the futurethreadKey
- object key where equals()
will be used to determine execution threadtask
- Runnable to be executedresult
- Result to be returned from future when task completespublic <T> ListenableFuture<T> submit(java.lang.Object threadKey, java.util.concurrent.Callable<T> task)
T
- type of result returned from the futurethreadKey
- object key where equals()
will be used to determine execution threadtask
- Callable to be executed