Top Description Fields Constructors Methods
com.opencsv.bean.concurrent

pack-priv Class IntolerantThreadPoolExecutor<T>

extends ThreadPoolExecutor
implements Spliterator<T>
Class Inheritance
All Implemented Interfaces
java.util.Spliterator
Known Direct Subclasses
com.opencsv.bean.concurrent.LineExecutor, com.opencsv.bean.concurrent.BeanExecutor
Type Parameters
<T>
The type of the object being created by the threads run
Imports
com.opencsv.ICSVParser, com.opencsv.bean.util.OrderedObject, com.opencsv.exceptions.CsvException, org.apache.commons.collections4.ListValuedMap, org.apache.commons.collections4.multimap.ArrayListValuedHashMap, org.apache.commons.lang3.ArrayUtils, .ObjectUtils, java.util.*, java.util.concurrent.*, java.util.function.Consumer, java.util.stream.Collectors

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 java.lang.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 java.util.concurrent.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 java.util.stream.Stream out of the executor itself. This is most easily done with java.util.stream.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.

Author
Andrew Rucker Jones
Since
4.0

Field Summary

Modifier and TypeField and Description
protected AccumulateCsvResults<T>
accumulateThread

A separate thread that accumulates and orders results.

protected final Locale
errorLocale

The locale for error messages.

protected final SortedSet<Long>
expectedRecords

A list of the ordinals of data records still to be expected by the accumulator.

private final boolean
orderedResults

Determines whether resulting data sets have to be in the same order as the input.

private ConcurrentNavigableMap<Long, T>
resultantBeansMap

A sorted, concurrent map for the beans created.

protected final BlockingQueue<OrderedObject<T>>
resultQueue

A queue of the beans created.

private Throwable
terminalException

The exception that caused this Executor to stop executing.

private ListValuedMap<Long, CsvException>
thrownExceptionsMap

A multi-valued map for any exceptions captured.

protected final BlockingQueue<OrderedObject<CsvException>>
thrownExceptionsQueue

A queue of exceptions thrown by threads during processing.

Constructor Summary

AccessConstructor and Description
pack-priv
IntolerantThreadPoolExecutor(boolean
Whether order should be preserved in the results
orderedResults
,
Locale
The errorLocale to use for error messages.
errorLocale
)

Constructor for a thread pool executor that stops by itself as soon as any thread throws an exception.

Method Summary

Modifier and TypeMethod and Description
protected void
afterExecute(Runnable r, Throwable t)

Overrides java.util.concurrent.ThreadPoolExecutor.afterExecute.

Shuts the Executor down if the thread ended in an exception.

private boolean

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.
areMoreResultsAvailable
()

Determines whether more conversion results can be expected.

public int
characteristics()

Implements java.util.Spliterator.characteristics.

Returns a set of characteristics of this Spliterator and its elements.

protected void
checkExceptions()

Checks whether exceptions are available that should halt processing.

public void
complete()

Sends a signal to the Executor that it should shut down once all threads have completed.

public long
estimateSize()

Implements java.util.Spliterator.estimateSize.

Returns an estimate of the number of elements that would be encountered by a forEachRemaining traversal, or returns Long#MAX_VALUE if infinite, unknown, or too expensive to compute.

public List<CsvException>

Returns:

All exceptions captured
getCapturedExceptions
()

Returns exceptions captured during the conversion process if the conversion process was set not to propagate these errors up the call stack.

public Throwable

Returns:

The exception that halted one of the threads, which caused the executor to shut itself down
getTerminalException
()

If an unrecoverable exception was thrown during processing, it can be retrieved here.

private boolean
public void
prepare()

Prepares this Executor to receive jobs.

public List<Runnable>
shutdownNow()

Overrides java.util.concurrent.ThreadPoolExecutor.shutdownNow.

Implements java.util.concurrent.ExecutorService.shutdownNow.

Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.

public boolean
tryAdvance(Consumer<? super T> action)

Implements java.util.Spliterator.tryAdvance.

If a remaining element exists: performs the given action on it, returning true; else returns false.

public Spliterator<T>
trySplit()

Implements java.util.Spliterator.trySplit.

If this spliterator can be partitioned, returns a Spliterator covering elements, that will, upon return from this method, not be covered by this Spliterator.

Inherited from java.util.concurrent.ThreadPoolExecutor:
allowCoreThreadTimeOutallowsCoreThreadTimeOutawaitTerminationbeforeExecuteexecutefinalizegetActiveCountgetCompletedTaskCountgetCorePoolSizegetKeepAliveTimegetLargestPoolSizegetMaximumPoolSizegetPoolSizegetQueuegetRejectedExecutionHandlergetTaskCountgetThreadFactoryisShutdownisTerminatedisTerminatingprestartAllCoreThreadsprestartCoreThreadpurgeremovesetCorePoolSizesetKeepAliveTimesetMaximumPoolSizesetRejectedExecutionHandlersetThreadFactoryshutdownterminatedtoString

Field Detail

accumulateThreadback to summary
protected AccumulateCsvResults<T> accumulateThread

A separate thread that accumulates and orders results.

errorLocaleback to summary
protected final Locale errorLocale

The locale for error messages.

expectedRecordsback to summary
protected final SortedSet<Long> expectedRecords

A list of the ordinals of data records still to be expected by the accumulator.

orderedResultsback to summary
private final boolean orderedResults

Determines whether resulting data sets have to be in the same order as the input.

resultantBeansMapback to summary
private ConcurrentNavigableMap<Long, T> resultantBeansMap

A sorted, concurrent map for the beans created.

resultQueueback to summary
protected final BlockingQueue<OrderedObject<T>> resultQueue

A queue of the beans created.

terminalExceptionback to summary
private Throwable terminalException

The exception that caused this Executor to stop executing.

thrownExceptionsMapback to summary
private ListValuedMap<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.

thrownExceptionsQueueback to summary
protected final BlockingQueue<OrderedObject<CsvException>> thrownExceptionsQueue

A queue of exceptions thrown by threads during processing.

Constructor Detail

IntolerantThreadPoolExecutorback to summary
pack-priv IntolerantThreadPoolExecutor(boolean orderedResults, 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:boolean

Whether order should be preserved in the results

errorLocale:Locale

The errorLocale to use for error messages.

Method Detail

afterExecuteback to summary
protected void afterExecute(Runnable r, Throwable t)

Overrides java.util.concurrent.ThreadPoolExecutor.afterExecute.

Shuts the Executor down if the thread ended in an exception.

Annotations
@Override
areMoreResultsAvailableback to summary
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:boolean

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.

characteristicsback to summary
public int characteristics()

Implements java.util.Spliterator.characteristics.

Doc from java.util.Spliterator.characteristics.

Returns a set of characteristics of this Spliterator and its elements. The result is represented as ORed values from ORDERED, DISTINCT, SORTED, SIZED, NONNULL, IMMUTABLE, CONCURRENT, SUBSIZED. Repeated calls to characteristics() on a given spliterator, prior to or in-between calls to trySplit, should always return the same result.

If a Spliterator reports an inconsistent set of characteristics (either those returned from a single invocation or across multiple invocations), no guarantees can be made about any computation using this Spliterator.

Annotations
@Override
checkExceptionsback to summary
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.

completeback to summary
public void complete() throws InterruptedException

Sends a signal to the Executor that it should shut down once all threads have completed.

Exceptions
InterruptedException:
If the current thread is interrupted while waiting. Shouldn't be thrown, since the Executor waits indefinitely for all threads to end.
RejectedExecutionException:
If an exception during processing forced this Executor to shut down.
estimateSizeback to summary
public long estimateSize()

Implements java.util.Spliterator.estimateSize.

Doc from java.util.Spliterator.estimateSize.

Returns an estimate of the number of elements that would be encountered by a forEachRemaining traversal, or returns Long#MAX_VALUE if infinite, unknown, or too expensive to compute.

If this Spliterator is SIZED and has not yet been partially traversed or split, or this Spliterator is SUBSIZED and has not yet been partially traversed, this estimate must be an accurate count of elements that would be encountered by a complete traversal. Otherwise, this estimate may be arbitrarily inaccurate, but must decrease as specified across invocations of trySplit.

Annotations
@Override
getCapturedExceptionsback to summary
public 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:List<CsvException>

All exceptions captured

getTerminalExceptionback to summary
public Throwable getTerminalException()

If an unrecoverable exception was thrown during processing, it can be retrieved here.

Returns:Throwable

The exception that halted one of the threads, which caused the executor to shut itself down

isConversionCompleteback to summary
private boolean isConversionComplete()
prepareback to summary
public void prepare()

Prepares this Executor to receive jobs.

shutdownNowback to summary
public List<Runnable> shutdownNow()

Overrides java.util.concurrent.ThreadPoolExecutor.shutdownNow.

Implements java.util.concurrent.ExecutorService.shutdownNow.

Doc from java.util.concurrent.ThreadPoolExecutor.shutdownNow.

Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. These tasks are drained (removed) from the task queue upon return from this method.

This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. This implementation interrupts tasks via Thread#interrupt; any task that fails to respond to interrupts may never terminate.

Annotations
@Override
tryAdvanceback to summary
public boolean tryAdvance(Consumer<? super T> action)

Implements java.util.Spliterator.tryAdvance.

Doc from java.util.Spliterator.tryAdvance.

If a remaining element exists: performs the given action on it, returning true; else returns false. If this Spliterator is ORDERED the action is performed on the next element in encounter order. Exceptions thrown by the action are relayed to the caller.

Subsequent behavior of a spliterator is unspecified if the action throws an exception.

Annotations
@Override
trySplitback to summary
public Spliterator<T> trySplit()

Implements java.util.Spliterator.trySplit.

Doc from java.util.Spliterator.trySplit.

If this spliterator can be partitioned, returns a Spliterator covering elements, that will, upon return from this method, not be covered by this Spliterator.

If this Spliterator is ORDERED, the returned Spliterator must cover a strict prefix of the elements.

Unless this Spliterator covers an infinite number of elements, repeated calls to trySplit() must eventually return null. Upon non-null return:

  • the value reported for estimateSize() before splitting, must, after splitting, be greater than or equal to estimateSize() for this and the returned Spliterator; and
  • if this Spliterator is SUBSIZED, then estimateSize() for this spliterator before splitting must be equal to the sum of estimateSize() for this and the returned Spliterator after splitting.

This method may return null for any reason, including emptiness, inability to split after traversal has commenced, data structure constraints, and efficiency considerations.

Annotations
@Override