public interface BatchingExecutor
extends java.util.concurrent.Executor
Runnable.run()
calls
into a single Runnable passed to the original
Executor. This can be a useful optimization
because it bypasses the original context's task
queue and keeps related (nested) code on a single
thread which may improve CPU affinity. However,
if tasks passed to the Executor are blocking
or expensive, this optimization can prevent work-stealing
and make performance worse. Also, some ExecutionContext
may be fast enough natively that this optimization just
adds overhead.
The default ExecutionContext.global is already batching
or fast enough not to benefit from it; while
fromExecutor
and fromExecutorService
do NOT add
this optimization since they don't know whether the underlying
executor will benefit from it.
A batching executor can create deadlocks if code does
not use scala.concurrent.blocking
when it should,
because tasks created within other tasks will block
on the outer task completing.
This executor may run tasks in any order, including LIFO order.
There are no ordering guarantees.
WARNING: The underlying Executor's execute-method must not execute the submitted Runnable in the calling thread synchronously. It must enqueue/handoff the Runnable.
Modifier and Type | Interface and Description |
---|---|
private static class |
BatchingExecutor.AbstractBatch |
private static class |
BatchingExecutor.Batch |
private static class |
BatchingExecutor.BlockableBatch |
Modifier and Type | Method and Description |
---|---|
boolean |
batchable(java.lang.Runnable runnable)
Override this to define which runnables will be batched.
|
void |
execute(java.lang.Runnable runnable) |
boolean |
resubmitOnBlock() |
void |
unbatchedExecute(java.lang.Runnable r) |
void unbatchedExecute(java.lang.Runnable r)
boolean resubmitOnBlock()
void execute(java.lang.Runnable runnable)
execute
in interface java.util.concurrent.Executor
boolean batchable(java.lang.Runnable runnable)