Returns an
Executor that runs each task executed sequentially, such that no two tasks
are running concurrently. Submitted tasks have a happens-before order as defined in the Java
Language Specification.
The executor uses
delegate in order to
Executor#execute each task in
turn, and does not create any threads of its own.
After execution begins on a thread from the
delegate
Executor, tasks are
polled and executed from a task queue until there are no more tasks. The thread will not be
released until there are no more tasks to run.
If a task is submitted while a thread is executing tasks from the task queue, the thread
will not be released until that submitted task is also complete.
If a task is
Thread#interrupt while a task is running:
- execution will not stop until the task queue is empty.
- tasks will begin execution with the thread marked as not interrupted - any interruption
applies only to the task that was running at the point of interruption.
- if the thread was interrupted before the SequentialExecutor's worker begins execution,
the interrupt will be restored to the thread after it completes so that its
delegate Executor may process the interrupt.
- subtasks are run with the thread uninterrupted and interrupts received during execution
of a task are ignored.
RuntimeExceptions thrown by tasks are simply logged and the executor keeps trucking.
If an
Error is thrown, the error will propagate and execution will stop until the next
time a task is submitted.
When an
Error is thrown by an executed task, previously submitted tasks may never
run. An attempt will be made to restart execution on the next call to
execute. If the
delegate has begun to reject execution, the previously submitted tasks may never run,
despite not throwing a RejectedExecutionException synchronously with the call to
execute. If this behaviour is problematic, use an Executor with a single thread (e.g.
Executors#newSingleThreadExecutor).