Class SingleThreadedExecutor

java.lang.Object
org.jtrim2.executor.DelegatedTaskExecutorService
org.jtrim2.executor.SingleThreadedExecutor
All Implemented Interfaces:
Executor, ContextAwareTaskExecutor, ContextAwareTaskExecutorService, MonitorableTaskExecutor, MonitorableTaskExecutorService, TaskExecutor, TaskExecutorService

public final class SingleThreadedExecutor extends DelegatedTaskExecutorService implements MonitorableTaskExecutorService
Defines a TaskExecutorService executing submitted tasks on a single background thread. Tasks are guaranteed to be executed in a FIFO order and they are never executed concurrently, so this class might be conveniently used for synchronization purposes.

Note: Consider using ThreadPoolBuilder instead of directly creating an instance of ThreadPoolTaskExecutor.

Executing new tasks

Tasks can be submitted by one of the execute methods.

When a new task is submitted, SingleThreadedExecutor and the queue of this executor is not full: The task is added to the queue. If the worker thread of this executor has already been started, the worker will execute the newly added task after it finishes executing previously submitted tasks.

If the queue for tasks is full, the submit or execute method will block and wait until the task can be added to the queue.

Cancellation of tasks

Canceling a task which was not yet started and is still in the queue will immediately remove it from the queue and no references will be retained to the task (allowing it to be garbage collected if not referenced by external code).

Canceling a task will cause the CancellationToken passed to it, signal cancellation request. In this case the task may decide if it is to be canceled or not. If the task throws an OperationCanceledException, task execution is considered to be canceled. Note that if the task throws an OperationCanceledException it is always assumed to be canceled, even if the CancellationToken does not signal a cancellation request.

Number of referenced tasks

The maximum number of tasks referenced by a SingleThreadedExecutor at any given time is the maximum size of its queue plus one. The SingleThreadedExecutor will never reference tasks more than this. Note however, that not yet returned submit or execute methods always reference their task specified in their argument (obviously this is unavoidable) and there is no limit on how many times the user can concurrently call these methods.

Terminating SingleThreadedExecutor

The SingleThreadedExecutor must always be shut down when no longer needed, so that it may shutdown its worker thread. If the user fails to shut down the SingleThreadedExecutor (either by calling shutdown() or shutdownAndCancel()) and the garbage collector notifies the SingleThreadedExecutor that it has become unreachable (through finalizers), it will be logged as an error using the logging facility of Java (in a Level.SEVERE log message).

Thread safety

Methods of this class are safely accessible from multiple threads concurrently.

Synchronization transparency

Method of this class are not synchronization transparent unless otherwise noted.
See Also:
  • Constructor Details

    • SingleThreadedExecutor

      public SingleThreadedExecutor(String poolName)
      Creates a new SingleThreadedExecutor initialized with the specified name.

      The default maximum queue size is Integer.MAX_VALUE making it effectively unbounded.

      The default timeout value after idle threads stop is 5 seconds.

      The newly created SingleThreadedExecutor will not have any thread started. Threads will only be started when submitting tasks (as required).

      The default ThreadFactory will create non-daemon threads and the name of the started threads will contain the name of this executor.

      Note: Consider using ThreadPoolBuilder instead of directly creating an instance of ThreadPoolTaskExecutor.

      Parameters:
      poolName - the name of this SingleThreadedExecutor for logging and debugging purposes. Setting a descriptive name might help when debugging or reading logs. This argument cannot be null.
      Throws:
      IllegalArgumentException - thrown if an illegal value was specified for any of the int arguments
      NullPointerException - thrown if the specified name for this SingleThreadedExecutor is null
      See Also:
    • SingleThreadedExecutor

      public SingleThreadedExecutor(String poolName, int maxQueueSize)
      Creates a new SingleThreadedExecutor initialized with the given properties.

      The default timeout value after idle threads stop is 5 seconds.

      The newly created SingleThreadedExecutor will not have any thread started. Threads will only be started when submitting tasks (as required).

      The default ThreadFactory will create non-daemon threads and the name of the started threads will contain the name of this executor.

      Note: Consider using ThreadPoolBuilder instead of directly creating an instance of ThreadPoolTaskExecutor.

      Parameters:
      poolName - the name of this SingleThreadedExecutor for logging and debugging purposes. Setting a descriptive name might help when debugging or reading logs. This argument cannot be null.
      maxQueueSize - the maximum size of the internal queue to store tasks not yet executed due to the worker thread being busy executing tasks. This argument must greater than or equal to 1.
      Throws:
      IllegalArgumentException - thrown if an illegal value was specified for any of the int arguments
      NullPointerException - thrown if the specified name for this SingleThreadedExecutor is null
      See Also:
    • SingleThreadedExecutor

      public SingleThreadedExecutor(String poolName, int maxQueueSize, long idleTimeout, TimeUnit timeUnit)
      Creates a new SingleThreadedExecutor initialized with the given properties.

      The newly created SingleThreadedExecutor will not have any thread started. Threads will only be started when submitting tasks (as required).

      The default ThreadFactory will create non-daemon threads and the name of the started threads will contain the name of this executor.

      Note: Consider using ThreadPoolBuilder instead of directly creating an instance of ThreadPoolTaskExecutor.

      Parameters:
      poolName - the name of this SingleThreadedExecutor for logging and debugging purposes. Setting a descriptive name might help when debugging or reading logs. This argument cannot be null.
      maxQueueSize - the maximum size of the internal queue to store tasks not yet executed due to the worker thread being busy executing tasks. This argument must greater than or equal to 1..
      idleTimeout - the time in the given time unit after idle threads should stop. That is if a thread goes idle (i.e.: there are no submitted tasks), it will wait this amount of time before giving up waiting for submitted tasks. The thread may be restarted if needed later. It is recommended to use a reasonably low value for this argument (but not too low), so even if this SingleThreadedExecutor is not shut down (due to a bug), threads will still terminate allowing the JVM to terminate as well (if there are no more non-daemon threads). This argument must be greater than or equal to zero.
      timeUnit - the time unit of the idleTimeout argument. This argument cannot be null.
      Throws:
      IllegalArgumentException - thrown if an illegal value was specified for any of the int arguments
      NullPointerException - thrown if any of the arguments is null
      See Also:
  • Method Details

    • dontNeedShutdown

      public void dontNeedShutdown()
      Specifies that this SingleThreadedExecutor does not need to be shut down. Calling this method prevents this executor to be shut down automatically when there is no more reference to this executor, which also prevents logging a message if this executor has not been shut down. This method might be called if you do not plan to shutdown this executor but instead want to rely on the threads of this executor to automatically shutdown after a small timeout.
    • shutdown

      public void shutdown()
      Shuts down this TaskExecutorService, so that it will not execute tasks submitted to it after this method call returns.

      Already submitted tasks will execute normally but tasks submitted after this method returns will immediately be completed exceptionally with an OperationCanceledException.

      Note that it is possible, that some tasks are submitted concurrently with this call. Those tasks can be either canceled or executed normally, depending on the circumstances.

      If currently executing tasks should be canceled as well, use the TaskExecutorService.shutdownAndCancel() method to shutdown this TaskExecutorService.

      This method call is idempotent. That is, calling it multiple times must have no further effect.

      Specified by:
      shutdown in interface TaskExecutorService
      Overrides:
      shutdown in class DelegatedTaskExecutorService
      See Also:
    • shutdownAndCancel

      public void shutdownAndCancel()
      Shuts down this TaskExecutorService and cancels already submitted tasks, so that it will not execute tasks submitted to it after this method call returns.

      Already submitted tasks will be canceled and the tasks may detect this cancellation request by inspecting their CancellationToken but tasks submitted after this method returns will immediately be completed exceptionally with an OperationCanceledException.

      Note that it is possible, that some tasks are submitted concurrently with this call. Those tasks may be treated as if they were submitted before this method call or as if they were submitted after.

      If currently executing tasks should be left executing, use the TaskExecutorService.shutdown() method instead to shutdown this TaskExecutorService.

      This method call is idempotent. That is, calling it multiple times must have no further effect. Note however, that calling this method after the shutdown() method is meaningful because this method will cancel ongoing tasks.

      Specified by:
      shutdownAndCancel in interface TaskExecutorService
      Overrides:
      shutdownAndCancel in class DelegatedTaskExecutorService
      See Also:
    • setThreadFactory

      public void setThreadFactory(ThreadFactory threadFactory)
      Sets the ThreadFactory which is used to create worker threads for this executor. Already started worker threads are not affected by this method call but workers created after this method call will use the currently set ThreadFactory.

      It is recommended to call this method before submitting any task to this executor. Doing so guarantees that all worker threads of this executor will be created by the specified ThreadFactory.

      Parameters:
      threadFactory - the ThreadFactory which is used to create worker threads for this executor. This argument cannot be null.
      Throws:
      NullPointerException - thrown if the specified thread factory is null
    • setMaxQueueSize

      public void setMaxQueueSize(int maxQueueSize)
      Sets the maximum number of tasks allowed to be stored in the internal queue.

      Setting this property higher than it was set previously will have an immediate effect and currently blocking submit and execute will recheck if they can add the submitted task to the queue. Setting this property lower, however, will not remove tasks from the queue but will prevent more tasks to be added to the queue before the number of tasks in the queue drops below this limit.

      Parameters:
      maxQueueSize - the maximum number of tasks allowed to be stored in the internal queue. This argument must be greater than or equal to 1.
      Throws:
      IllegalArgumentException - if the specified maxQueueSize is less than 1
    • getMaxQueueSize

      public int getMaxQueueSize()
      Returns the currently set maximum size for the queue of tasks scheduled to be executed.

      The return value of this method is for information purpose only. Due to concurrent sets and already queued tasks, there is no guarantee that the return value is truly being honored at the moment. See setMaxQueueSize for details on how this property works.

      Returns:
      the currently set maximum size for the queue of tasks scheduled to be executed. This value is always greater than or equal to one.
    • setIdleTimeout

      public void setIdleTimeout(long idleTimeout, TimeUnit timeUnit)
      Sets the timeout value after idle threads should terminate. That is, threads will terminate if they waited for at least this much time and there was no submitted task for them to execute.

      Setting this property has an immediate effect.

      Parameters:
      idleTimeout - the timeout value in the given time unit after idle threads should terminate. This argument must be greater than or equal to zero.
      timeUnit - the time unit of the idleTimeout argument. This argument cannot be null.
      Throws:
      IllegalArgumentException - thrown if the specified timeout value is less than zero
      NullPointerException - thrown if the specified time unit argument is null
    • getIdleTimeout

      public long getIdleTimeout(TimeUnit timeUnit)
      Returns the currently set timeout value after idle threads should stop.

      The return value of this method is for information purpose only. Due to concurrent sets, there is no guarantee that the return value is truly being honored at the moment. See setIdleTimeout for details on how this property works.

      Parameters:
      timeUnit - the time unit in which the result is request. This argument cannot be null.
      Returns:
      the currently set timeout value after idle threads should stop. The return value might not be exactly what was set by the previous invocation to setIdleTimeout due to rounding errors. This method always returns a values greater than or equal to zero.
      Throws:
      NullPointerException - thrown if the specified time unit is null
    • getPoolName

      public String getPoolName()
      Returns the name of this SingleThreadedExecutor as specified at construction time.
      Returns:
      the name of this SingleThreadedExecutor as specified at construction time. This method never returns null.
    • getNumberOfQueuedTasks

      public long getNumberOfQueuedTasks()
      Returns the approximate number of tasks currently queued to this executor. The queued tasks are not currently executing but are scheduled to be executed in the future.

      Note that the value returned by this method should be considered unreliable and cannot be used for synchronization purposes.

      Specified by:
      getNumberOfQueuedTasks in interface MonitorableTaskExecutor
      Returns:
      the approximate number of tasks currently queued to this executor. This method always returns a value greater than or equal to zero.
    • getNumberOfExecutingTasks

      public long getNumberOfExecutingTasks()
      Returns the approximate number of tasks currently being executed.

      Note that the value returned by this method should be considered unreliable and cannot be used for synchronization purposes.

      Implementation note: This method may only return zero or one.

      Specified by:
      getNumberOfExecutingTasks in interface MonitorableTaskExecutor
      Returns:
      the approximate number of tasks currently being executed. This method always returns a value greater than or equal to zero.
    • isExecutingInThis

      public boolean isExecutingInThis()
      Returns true if the calling code is executing in the context of this executor. That is, it is executed by a task submitted to this executor.

      This method can be used to check that a method call is executing in the context it was designed for.

      Specified by:
      isExecutingInThis in interface ContextAwareTaskExecutor
      Returns:
      true if the calling code is executing in the context of this executor, false otherwise
    • toString

      public String toString()
      Returns the string representation of this executor in no particular format.

      This method is intended to be used for debugging only.

      Overrides:
      toString in class DelegatedTaskExecutorService
      Returns:
      the string representation of this object in no particular format. This method never returns null.