Class AdaptiveExecutionStrategy
- All Implemented Interfaces:
Runnable
,Container
,Destroyable
,Dumpable
,Dumpable.DumpableContainer
,LifeCycle
,ExecutionStrategy
- Direct Known Subclasses:
EatWhatYouKill
An adaptive execution strategy that uses the Invocable
status
of both the task and the current thread to select an optimal strategy
that prioritizes executing the task immediately in the current
producing thread if it can be done so without thread starvation issues.
This strategy selects between the following sub-strategies:
- ProduceConsume(PC)
- The producing thread consumes the task by running it directly and then continues to produce.
- ProduceInvokeConsume(PIC)
- The producing thread consumes the task by running it with
Invocable.invokeNonBlocking(Runnable)
and then continues to produce. - ProduceExecuteConsume(PEC)
- The producing thread dispatches the task to a thread pool to be executed and then continues to produce.
- ExecuteProduceConsume(EPC)
- The producing thread consumes dispatches a pending producer to a thread pool, then consumes the task by running it directly (as in PC mode), then races with the pending producer thread to take over production.
The sub-strategy is selected as follows:
- PC
- If the produced task is
Invocable.InvocationType.NON_BLOCKING
. - EPC
- If the producing thread is not
Invocable.InvocationType.NON_BLOCKING
and a pending producer thread is available, either because there is already a pending producer or one is successfully started withTryExecutor.tryExecute(Runnable)
. - PIC
- If the produced task is
Invocable.InvocationType.EITHER
and EPC was not selected. - PEC
- Otherwise.
Because of the preference for PC
mode, on a multicore machine with many
many Invocable.InvocationType.NON_BLOCKING
tasks, multiple instances of the strategy may be
required to keep all CPUs on the system busy.
Since the producing thread may be invoked with Invocable.invokeNonBlocking(Runnable)
this allows AdaptiveExecutionStrategy
s to be efficiently and safely chained: a task
produced by one execution strategy may become itself be a producer in a second execution strategy
(e.g. an IO selector may use an execution strategy to handle multiple connections and each
connection may use a execution strategy to handle multiplexed channels/streams within the connection).
A task containing another AdaptiveExecutionStrategy
should identify as
Invocable.InvocationType.EITHER
so when there are no pending producers threads available to
the first strategy, then it may invoke the second as Invocable.InvocationType.NON_BLOCKING
.
This avoids starvation as the production on the second strategy can always be executed,
but without the risk that it may block the last available producer for the first strategy.
This strategy was previously named EatWhatYouKill (EWYK) because its preference for a producer to directly consume the tasks that it produces is similar to a hunting proverb that says that a hunter should eat (i.e. consume) what they kill (i.e. produced).
-
Nested Class Summary
Nested classes/interfaces inherited from class org.eclipse.jetty.util.component.AbstractLifeCycle
AbstractLifeCycle.AbstractLifeCycleListener, AbstractLifeCycle.StopException
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.component.Container
Container.InheritedListener, Container.Listener
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.component.Dumpable
Dumpable.DumpableContainer
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.thread.ExecutionStrategy
ExecutionStrategy.Producer
Nested classes/interfaces inherited from interface org.eclipse.jetty.util.component.LifeCycle
LifeCycle.Listener
-
Field Summary
-
Constructor Summary
ConstructorDescriptionAdaptiveExecutionStrategy
(ExecutionStrategy.Producer producer, Executor executor) -
Method Summary
Methods inherited from class org.eclipse.jetty.util.component.ContainerLifeCycle
addBean, addBean, addEventListener, addManaged, contains, destroy, doStart, doStop, dump, dump, dump, dumpObjects, dumpStdErr, getBean, getBeans, getBeans, getContainedBeans, getContainedBeans, isAuto, isManaged, isUnmanaged, manage, removeBean, removeBeans, removeEventListener, setBeans, start, stop, unmanage, updateBean, updateBean, updateBeans, updateBeans
Methods inherited from class org.eclipse.jetty.util.component.AbstractLifeCycle
getEventListeners, getState, getState, isFailed, isRunning, isStarted, isStarting, isStopped, isStopping, setEventListeners, start, stop
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Methods inherited from interface org.eclipse.jetty.util.component.Container
getCachedBeans, getEventListeners
Methods inherited from interface org.eclipse.jetty.util.component.Dumpable.DumpableContainer
isDumpable
-
Constructor Details
-
AdaptiveExecutionStrategy
- Parameters:
producer
- The producer of tasks to be consumed.executor
- The executor to be used for executing producers or consumers, depending on the sub-strategy.
-
-
Method Details
-
dispatch
public void dispatch()Description copied from interface:ExecutionStrategy
Initiates (or resumes) the task production and consumption.
This method guarantees that the task is never run by the thread that called this method.
TODO review the need for this (only used by HTTP2 push)- Specified by:
dispatch
in interfaceExecutionStrategy
- See Also:
-
produce
public void produce()Description copied from interface:ExecutionStrategy
Initiates (or resumes) the task production and consumption.
The produced task may be run by the same thread that called this method.
- Specified by:
produce
in interfaceExecutionStrategy
- See Also:
-
run
public void run() -
isUseVirtualThreads
@ManagedAttribute(value="whether this execution strategy uses virtual threads", readonly=true) public boolean isUseVirtualThreads() -
getPCTasksConsumed
@ManagedAttribute(value="number of tasks consumed with PC mode", readonly=true) public long getPCTasksConsumed() -
getPICTasksExecuted
@ManagedAttribute(value="number of tasks executed with PIC mode", readonly=true) public long getPICTasksExecuted() -
getPECTasksExecuted
@ManagedAttribute(value="number of tasks executed with PEC mode", readonly=true) public long getPECTasksExecuted() -
getEPCTasksConsumed
@ManagedAttribute(value="number of tasks consumed with EPC mode", readonly=true) public long getEPCTasksConsumed() -
isIdle
@ManagedAttribute(value="whether this execution strategy is idle", readonly=true) public boolean isIdle() -
reset
-
toString
- Overrides:
toString
in classAbstractLifeCycle
-
toStringLocked
-