Class IntolerantThreadPoolExecutor<T>

  • Type Parameters:
    T - The type of the object being created by the threads run
    All Implemented Interfaces:
    java.util.concurrent.Executor, java.util.concurrent.ExecutorService, java.util.Spliterator<T>
    Direct Known Subclasses:
    BeanExecutor, LineExecutor

    class IntolerantThreadPoolExecutor<T>
    extends java.util.concurrent.ThreadPoolExecutor
    implements java.util.Spliterator<T>
    This ThreadPoolExecutor automatically shuts down on any failed thread.

    This is the historically established precedent for dealing with input errors in opencsv. This implementation expects all uncaught exceptions from its threads to be wrapped in a RuntimeException. The number of threads in the pool is fixed.

    It is not intended for this executor to be instantiated and receive jobs directly. There are function-specific derived classes for that purpose.

    This executor adds significant logic to the basic idea of an Executor, and thus must be used differently from other executors. Usage follows this pattern:

    1. prepare()
    2. Submit tasks. This is not intended to be done directly to this class, but rather to one of the submission methods of the derived classes.
    3. complete()
    4. The results are had by creating a Stream out of the executor itself. This is most easily done with StreamSupport.stream(Spliterator, boolean)
    5. Possibly getCapturedExceptions()

    The execution structure of this class is:

    1. The main thread (outside of this executor) parses input and passes it on to
    2. This executor, which performs a number of conversions in parallel and passes these results and any resultant errors to
    3. The accumulator, which creates an ordered list of the results.

    The threads in the executor queue their results in a thread-safe queue, which should be O(1), minimizing wait time due to synchronization. The accumulator then removes items from the queue and inserts them into a sorted data structure, which is O(log n) on average and O(n) in the worst case. If the user has told us she doesn't need sorted data, the accumulator is not necessary, and thus is not started.

    Since:
    4.0
    • Nested Class Summary

      • Nested classes/interfaces inherited from class java.util.concurrent.ThreadPoolExecutor

        java.util.concurrent.ThreadPoolExecutor.AbortPolicy, java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy, java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy, java.util.concurrent.ThreadPoolExecutor.DiscardPolicy
      • Nested classes/interfaces inherited from interface java.util.Spliterator

        java.util.Spliterator.OfDouble, java.util.Spliterator.OfInt, java.util.Spliterator.OfLong, java.util.Spliterator.OfPrimitive<T extends java.lang.Object,​T_CONS extends java.lang.Object,​T_SPLITR extends java.util.Spliterator.OfPrimitive<T,​T_CONS,​T_SPLITR>>
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected AccumulateCsvResults<T> accumulateThread
      A separate thread that accumulates and orders results.
      protected java.util.Locale errorLocale
      The locale for error messages.
      protected java.util.SortedSet<java.lang.Long> expectedRecords
      A list of the ordinals of data records still to be expected by the accumulator.
      private boolean orderedResults
      Determines whether resulting data sets have to be in the same order as the input.
      private java.util.concurrent.ConcurrentNavigableMap<java.lang.Long,​T> resultantBeansMap
      A sorted, concurrent map for the beans created.
      protected java.util.concurrent.BlockingQueue<OrderedObject<T>> resultQueue
      A queue of the beans created.
      private java.lang.Throwable terminalException
      The exception that caused this Executor to stop executing.
      private org.apache.commons.collections4.ListValuedMap<java.lang.Long,​CsvException> thrownExceptionsMap
      A multi-valued map for any exceptions captured.
      protected java.util.concurrent.BlockingQueue<OrderedObject<CsvException>> thrownExceptionsQueue
      A queue of exceptions thrown by threads during processing.
      • Fields inherited from interface java.util.Spliterator

        CONCURRENT, DISTINCT, IMMUTABLE, NONNULL, ORDERED, SIZED, SORTED, SUBSIZED
    • Constructor Summary

      Constructors 
      Constructor Description
      IntolerantThreadPoolExecutor​(boolean orderedResults, java.util.Locale errorLocale)
      Constructor for a thread pool executor that stops by itself as soon as any thread throws an exception.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void afterExecute​(java.lang.Runnable r, java.lang.Throwable t)
      Shuts the Executor down if the thread ended in an exception.
      private boolean areMoreResultsAvailable()
      Determines whether more conversion results can be expected.
      int characteristics()  
      protected void checkExceptions()
      Checks whether exceptions are available that should halt processing.
      void complete()
      Sends a signal to the Executor that it should shut down once all threads have completed.
      long estimateSize()  
      java.util.List<CsvException> getCapturedExceptions()
      Returns exceptions captured during the conversion process if the conversion process was set not to propagate these errors up the call stack.
      java.lang.Throwable getTerminalException()
      If an unrecoverable exception was thrown during processing, it can be retrieved here.
      private boolean isConversionComplete()  
      void prepare()
      Prepares this Executor to receive jobs.
      java.util.List<java.lang.Runnable> shutdownNow()  
      boolean tryAdvance​(java.util.function.Consumer<? super T> action)  
      java.util.Spliterator<T> trySplit()  
      • Methods inherited from class java.util.concurrent.ThreadPoolExecutor

        allowCoreThreadTimeOut, allowsCoreThreadTimeOut, awaitTermination, beforeExecute, execute, finalize, getActiveCount, getCompletedTaskCount, getCorePoolSize, getKeepAliveTime, getLargestPoolSize, getMaximumPoolSize, getPoolSize, getQueue, getRejectedExecutionHandler, getTaskCount, getThreadFactory, isShutdown, isTerminated, isTerminating, prestartAllCoreThreads, prestartCoreThread, purge, remove, setCorePoolSize, setKeepAliveTime, setMaximumPoolSize, setRejectedExecutionHandler, setThreadFactory, shutdown, terminated, toString
      • Methods inherited from class java.util.concurrent.AbstractExecutorService

        invokeAll, invokeAll, invokeAny, invokeAny, newTaskFor, newTaskFor, submit, submit, submit
      • Methods inherited from class java.lang.Object

        clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.util.Spliterator

        forEachRemaining, getComparator, getExactSizeIfKnown, hasCharacteristics
    • Field Detail

      • resultQueue

        protected final java.util.concurrent.BlockingQueue<OrderedObject<T>> resultQueue
        A queue of the beans created.
      • thrownExceptionsQueue

        protected final java.util.concurrent.BlockingQueue<OrderedObject<CsvException>> thrownExceptionsQueue
        A queue of exceptions thrown by threads during processing.
      • resultantBeansMap

        private java.util.concurrent.ConcurrentNavigableMap<java.lang.Long,​T> resultantBeansMap
        A sorted, concurrent map for the beans created.
      • thrownExceptionsMap

        private org.apache.commons.collections4.ListValuedMap<java.lang.Long,​CsvException> thrownExceptionsMap
        A multi-valued map for any exceptions captured.

        The multi-valued part is important because the same line can throw more than one exception.

        All access to this variable must be synchronized.

      • accumulateThread

        protected AccumulateCsvResults<T> accumulateThread
        A separate thread that accumulates and orders results.
      • expectedRecords

        protected final java.util.SortedSet<java.lang.Long> expectedRecords
        A list of the ordinals of data records still to be expected by the accumulator.
      • orderedResults

        private final boolean orderedResults
        Determines whether resulting data sets have to be in the same order as the input.
      • errorLocale

        protected final java.util.Locale errorLocale
        The locale for error messages.
      • terminalException

        private java.lang.Throwable terminalException
        The exception that caused this Executor to stop executing.
    • Constructor Detail

      • IntolerantThreadPoolExecutor

        IntolerantThreadPoolExecutor​(boolean orderedResults,
                                     java.util.Locale errorLocale)
        Constructor for a thread pool executor that stops by itself as soon as any thread throws an exception. Threads never time out and the queue for inbound work is unbounded.
        Parameters:
        orderedResults - Whether order should be preserved in the results
        errorLocale - The errorLocale to use for error messages.
    • Method Detail

      • prepare

        public void prepare()
        Prepares this Executor to receive jobs.
      • complete

        public void complete()
                      throws java.lang.InterruptedException
        Sends a signal to the Executor that it should shut down once all threads have completed.
        Throws:
        java.lang.InterruptedException - If the current thread is interrupted while waiting. Shouldn't be thrown, since the Executor waits indefinitely for all threads to end.
        java.util.concurrent.RejectedExecutionException - If an exception during processing forced this Executor to shut down.
      • getCapturedExceptions

        public java.util.List<CsvException> getCapturedExceptions()
        Returns exceptions captured during the conversion process if the conversion process was set not to propagate these errors up the call stack. The call is nondestructive.
        Returns:
        All exceptions captured
      • shutdownNow

        public java.util.List<java.lang.Runnable> shutdownNow()
        Specified by:
        shutdownNow in interface java.util.concurrent.ExecutorService
        Overrides:
        shutdownNow in class java.util.concurrent.ThreadPoolExecutor
      • afterExecute

        protected void afterExecute​(java.lang.Runnable r,
                                    java.lang.Throwable t)
        Shuts the Executor down if the thread ended in an exception.
        Overrides:
        afterExecute in class java.util.concurrent.ThreadPoolExecutor
        Parameters:
        r -
        t -
      • getTerminalException

        public java.lang.Throwable getTerminalException()
        If an unrecoverable exception was thrown during processing, it can be retrieved here.
        Returns:
        The exception that halted one of the threads, which caused the executor to shut itself down
      • checkExceptions

        protected void checkExceptions()
        Checks whether exceptions are available that should halt processing. This is the case with unrecoverable errors, such as parsing the input, or if exceptions in conversion should be thrown by request of the user.
      • isConversionComplete

        private boolean isConversionComplete()
      • areMoreResultsAvailable

        private boolean areMoreResultsAvailable()
        Determines whether more conversion results can be expected. Since Spliterators have no way of indicating that they don't have a result at the moment, but might in the future, we must ensure that every call to tryAdvance(Consumer) or trySplit() only returns null if the entire conversion apparatus has shut down and all result queues are cleared. Thus, this method waits until either that is true, or there is truly at least one result that can be returned to users of the Spliterator interface.
        Returns:
        false if conversion is complete and no more results can ever be expected out of this Spliterator, true otherwise. If true is returned, it is guaranteed that at least one result is available immediately to the caller.
      • tryAdvance

        public boolean tryAdvance​(java.util.function.Consumer<? super T> action)
        Specified by:
        tryAdvance in interface java.util.Spliterator<T>
      • trySplit

        public java.util.Spliterator<T> trySplit()
        Specified by:
        trySplit in interface java.util.Spliterator<T>
      • estimateSize

        public long estimateSize()
        Specified by:
        estimateSize in interface java.util.Spliterator<T>
      • characteristics

        public int characteristics()
        Specified by:
        characteristics in interface java.util.Spliterator<T>