Class ConseqExecutor
- java.lang.Object
-
- conseq4j.execute.ConseqExecutor
-
- All Implemented Interfaces:
SequentialExecutor,Terminable
@ThreadSafe public final class ConseqExecutor extends Object implements SequentialExecutor
Relies on the JDKCompletableFutureas the sequential executor of the tasks under the same sequence key.- Author:
- Qingtian Wang
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classConseqExecutor.BuilderConseqExecutorbuilder static inner class.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description CompletableFuture<Void>execute(@NonNull Runnable command, @NonNull Object sequenceKey)static ConseqExecutorfrom(ThreadPoolExecutor workerThreadPool)booleanisTerminated()Nonblockingstatic ConseqExecutornewInstance()static ConseqExecutornewInstance(int concurrency)voidshutdown()Nonblocking, initiates an orderly shutdown of all managed thread resources.<T> CompletableFuture<T>submit(@NonNull Callable<T> task, @NonNull Object sequenceKey)Tasks of different sequence keys execute in parallel, pending thread availability from the backingworkerThreadPool.
-
-
-
Method Detail
-
newInstance
@Nonnull public static ConseqExecutor newInstance()
- Returns:
- conseq executor with default concurrency
-
newInstance
@Nonnull public static ConseqExecutor newInstance(int concurrency)
- Parameters:
concurrency- max number of tasks that can be run in parallel by the returned executor instance. This is set as the max capacity of theworkerThreadPool- Returns:
- conseq executor with given concurrency
-
from
public static ConseqExecutor from(ThreadPoolExecutor workerThreadPool)
- Parameters:
workerThreadPool- the worker thread pool that facilitates the overall async execution, independent of the submitted tasks.- Returns:
- new ConseqExecutor instance backed by the specified workerThreadPool
-
execute
public CompletableFuture<Void> execute(@NonNull @NonNull Runnable command, @NonNull @NonNull Object sequenceKey)
- Specified by:
executein interfaceSequentialExecutor- Parameters:
command- the command to run asynchronously in proper sequencesequenceKey- the key under which this task should be sequenced- Returns:
- future result of the command, not downcast-able from the basic
Futureinterface. - See Also:
submit(Callable, Object)
-
submit
public <T> CompletableFuture<T> submit(@NonNull @NonNull Callable<T> task, @NonNull @NonNull Object sequenceKey)
Tasks of different sequence keys execute in parallel, pending thread availability from the backingworkerThreadPool.Sequential execution of tasks under the same/equal sequence key is achieved by linearly chaining/queuing the task/work stages of the same key, leveraging the
CompletableFutureAPI.A
ConcurrentMapis employed to keep track of each sequence key's pending tasks status. Each map entry represents an active sequential executor in-service for all the tasks under the same sequence key; the entry's value is to hold the most recently added task as the tail of the FIFO task queue of the active executor. With this executor map, an active executor can be located by its sequence key so that a subsequent task of the same key can be queued/chained behind the previous task. If no active executor exists in the map for the submitted task's sequence key, a new entry/executor will be created. Before added to the tail of the task queue, each task will be converted to a new corresponding work stage (of typeCompletableFuture). If there already exists an entry/work stage of the same sequence key in the map, the current work stage will be chained to execute behind the existing work stage and replace the existing stage as the tail of the task queue in the map entry. This new work stage will not start executing before the previous stage completes, and will have to finish executing before the next task's work stage can start executing. Such linear progression of the work tasks/stages ensures the sequential-ness of task execution under the same sequence key.A separate administrative task/stage is triggered to run at the completion of each work task/stage. Under the same sequence key, this admin task will locate the executor entry in the map, and remove the entry if its work stage is complete. Otherwise, if the work stage is not complete, the admin task does nothing; the incomplete work stage stays in the map under the same sequence key, ready to be trailed by the next work stage. This administration ensures that every executor entry ever put on the map is eventually cleaned up and removed as long as every work stage runs to complete. Although always chained after the completion of a work stage, the admin task/stage is never added to the task work queue on the executor map and has no effect on the overall sequential-ness of the work stage executions.
- Specified by:
submitin interfaceSequentialExecutor- Type Parameters:
T- the type of the task's result- Parameters:
task- the task to be called asynchronously with proper sequencesequenceKey- the key under which this task should be sequenced- Returns:
- future result of the task, not downcast-able from the basic
Futureinterface.
-
shutdown
public void shutdown()
Description copied from interface:TerminableNonblocking, initiates an orderly shutdown of all managed thread resources. Previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.- Specified by:
shutdownin interfaceTerminable
-
isTerminated
public boolean isTerminated()
Description copied from interface:TerminableNonblocking- Specified by:
isTerminatedin interfaceTerminable- Returns:
- true if all tasks of all managed executors have completed following shut down. Note that isTerminated is never true unless shutdown was called first.
-
-