Class ExecutionSequencer.TaskNonReentrantExecutor
- java.lang.Object
-
- java.util.concurrent.atomic.AtomicReference<ExecutionSequencer.RunningState>
-
- com.google.common.util.concurrent.ExecutionSequencer.TaskNonReentrantExecutor
-
- All Implemented Interfaces:
java.io.Serializable
,java.lang.Runnable
,java.util.concurrent.Executor
- Enclosing class:
- ExecutionSequencer
private static final class ExecutionSequencer.TaskNonReentrantExecutor extends java.util.concurrent.atomic.AtomicReference<ExecutionSequencer.RunningState> implements java.util.concurrent.Executor, java.lang.Runnable
This class helps avoid a StackOverflowError when large numbers of tasks are submitted withMoreExecutors.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
Fields Modifier and Type Field Description (package private) java.util.concurrent.Executor
delegate
Executor the task was set to run on.(package private) ExecutionSequencer
sequencer
Used to update and read the latestTaskQueue field.(package private) java.lang.Thread
submitting
Thread that called execute().(package private) java.lang.Runnable
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.
-
Constructor Summary
Constructors Modifier Constructor Description private
TaskNonReentrantExecutor(java.util.concurrent.Executor delegate, ExecutionSequencer sequencer)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
execute(java.lang.Runnable task)
void
run()
private boolean
trySetCancelled()
private boolean
trySetStarted()
-
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 Detail
-
sequencer
@CheckForNull ExecutionSequencer sequencer
Used to update and read the latestTaskQueue field. Set to null once the runnable has been run or queued.
-
delegate
@CheckForNull java.util.concurrent.Executor delegate
Executor the task was set to run on. Set to null when the task has been queued, run, or cancelled.
-
task
@CheckForNull java.lang.Runnable 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
@CheckForNull java.lang.Thread submitting
Thread that called execute(). Set in execute, cleared when delegate.execute() returns.
-
-
Constructor Detail
-
TaskNonReentrantExecutor
private TaskNonReentrantExecutor(java.util.concurrent.Executor delegate, ExecutionSequencer sequencer)
-
-
Method Detail
-
execute
public void execute(java.lang.Runnable task)
- Specified by:
execute
in interfacejava.util.concurrent.Executor
-
run
public void run()
- Specified by:
run
in interfacejava.lang.Runnable
-
trySetStarted
private boolean trySetStarted()
-
trySetCancelled
private boolean trySetCancelled()
-
-