Class ExecutionSequencer.TaskNonReentrantExecutor
- All Implemented Interfaces:
Serializable
,Runnable
,Executor
- Enclosing class:
ExecutionSequencer
MoreExecutors.directExecutor()
. Normally, when the first future completes, all the other
tasks would be called recursively. Here, we detect that the delegate executor is executing
inline, and maintain a queue to dispatch tasks iteratively. There is one instance of this class
per call to submit() or submitAsync(), and each instance supports only one call to execute().
This class would certainly be simpler and easier to reason about if it were built with ThreadLocal; however, ThreadLocal is not well optimized for the case where the ThreadLocal is non-static, and is initialized/removed frequently - this causes churn in the Thread specific hashmaps. Using a static ThreadLocal to avoid that overhead would mean that different ExecutionSequencer objects interfere with each other, which would be undesirable, in addition to increasing the memory footprint of every thread that interacted with it. In order to release entries in thread-specific maps when the ThreadLocal object itself is no longer referenced, ThreadLocal is usually implemented with a WeakReference, which can have negative performance properties; for example, calling WeakReference.get() on Android will block during an otherwise-concurrent GC cycle.
-
Field Summary
FieldsModifier and TypeFieldDescription(package private) Executor
Executor the task was set to run on.(package private) ExecutionSequencer
Used to update and read the latestTaskQueue field.(package private) Thread
Thread that called execute().(package private) Runnable
Set before calling delegate.execute(); set to null once run, so that it can be GCed; this object may live on after, if submitAsync returns an incomplete future. -
Constructor Summary
ConstructorsModifierConstructorDescriptionprivate
TaskNonReentrantExecutor
(Executor delegate, ExecutionSequencer sequencer) -
Method Summary
Methods inherited from class java.util.concurrent.atomic.AtomicReference
accumulateAndGet, compareAndExchange, compareAndExchangeAcquire, compareAndExchangeRelease, compareAndSet, get, getAcquire, getAndAccumulate, getAndSet, getAndUpdate, getOpaque, getPlain, lazySet, set, setOpaque, setPlain, setRelease, toString, updateAndGet, weakCompareAndSet, weakCompareAndSetAcquire, weakCompareAndSetPlain, weakCompareAndSetRelease, weakCompareAndSetVolatile
-
Field Details
-
sequencer
Used to update and read the latestTaskQueue field. Set to null once the runnable has been run or queued. -
delegate
Executor the task was set to run on. Set to null when the task has been queued, run, or cancelled. -
task
Set before calling delegate.execute(); set to null once run, so that it can be GCed; this object may live on after, if submitAsync returns an incomplete future. -
submitting
Thread that called execute(). Set in execute, cleared when delegate.execute() returns.
-
-
Constructor Details
-
TaskNonReentrantExecutor
-
-
Method Details