Class SerializingExecutor

  • All Implemented Interfaces:
    java.util.concurrent.Executor

    @GwtIncompatible
    final class SerializingExecutor
    extends java.lang.Object
    implements java.util.concurrent.Executor
    Executor ensuring that all Runnables submitted are executed in order, using the provided Executor, and serially such that no two will ever be running at the same time.

    Tasks submitted to execute(Runnable) are executed in FIFO order.

    Tasks can also be prepended to the queue to be executed in LIFO order before any other submitted tasks. Primarily intended for the currently executing task to be able to schedule a continuation task.

    Execution on the queue can be suspended, e.g. while waiting for an RPC, and execution can be resumed later.

    The execution of tasks is done by one thread as long as there are tasks left in the queue and execution has not been suspended. (Even if one task is interrupted, execution of subsequent tasks continues.) 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 it is restarted by external calls.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private class  SerializingExecutor.QueueWorker
      Worker that runs tasks off the queue until it is empty or the queue is suspended.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.util.concurrent.Executor executor
      Underlying executor that all submitted Runnable objects are run on.
      private java.lang.Object internalLock  
      private boolean isWorkerRunning  
      private static java.util.logging.Logger log  
      private java.util.Deque<java.lang.Runnable> queue  
      private int suspensions  
    • Constructor Summary

      Constructors 
      Constructor Description
      SerializingExecutor​(java.util.concurrent.Executor executor)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void execute​(java.lang.Runnable task)
      Adds a task to the queue and makes sure a worker thread is running, unless the queue has been suspended.
      void executeFirst​(java.lang.Runnable task)
      Prepends a task to the front of the queue and makes sure a worker thread is running, unless the queue has been suspended.
      void resume()
      Continue execution of tasks after a call to suspend().
      private void startQueueWorker()  
      void suspend()
      Suspends the running of tasks until resume() is called.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • log

        private static final java.util.logging.Logger log
      • executor

        private final java.util.concurrent.Executor executor
        Underlying executor that all submitted Runnable objects are run on.
      • queue

        private final java.util.Deque<java.lang.Runnable> queue
      • isWorkerRunning

        private boolean isWorkerRunning
      • suspensions

        private int suspensions
      • internalLock

        private final java.lang.Object internalLock
    • Constructor Detail

      • SerializingExecutor

        public SerializingExecutor​(java.util.concurrent.Executor executor)
    • Method Detail

      • execute

        public void execute​(java.lang.Runnable task)
        Adds a task to the queue and makes sure a worker thread is running, unless the queue has been suspended.

        If this method throws, e.g. a RejectedExecutionException from the delegate executor, execution of tasks will stop until a call to this method or to resume() is made.

        Specified by:
        execute in interface java.util.concurrent.Executor
      • executeFirst

        public void executeFirst​(java.lang.Runnable task)
        Prepends a task to the front of the queue and makes sure a worker thread is running, unless the queue has been suspended.
      • suspend

        public void suspend()
        Suspends the running of tasks until resume() is called. This can be called multiple times to increase the suspensions count and execution will not continue until resume() has been called the same number of times as suspend has been.

        Any task that has already been pulled off the queue for execution will be completed before execution is suspended.

      • resume

        public void resume()
        Continue execution of tasks after a call to suspend(). More accurately, decreases the suspension counter, as has been incremented by calls to suspend(), and resumes execution if the suspension counter is zero.

        If this method throws, e.g. a RejectedExecutionException from the delegate executor, execution of tasks will stop until a call to this method or to execute(Runnable) or executeFirst(Runnable) is made.

        Throws:
        java.lang.IllegalStateException - if this executor is not suspended.
      • startQueueWorker

        private void startQueueWorker()