SerialExecutor Pattern¶
The SerialExecutor Pattern is a concurrency design pattern used to ensure that a series of tasks are executed sequentially, even when submitted to a multi-threaded or asynchronous executor.^[600-developer__big-data__netty__netty-EventLoopGroup.md]
Implementation Details¶
The pattern is typically implemented by wrapping an existing Executor instance.^[600-developer__big-data__netty__netty-EventLoopGroup.md] Internally, it maintains a queue (such as an ArrayDeque) to hold pending Runnable tasks and a reference to the currently active task.^[600-developer__big-data__netty__netty-EventLoopGroup.md]
Execution Logic¶
When a new task is submitted via the execute method, it is wrapped and added to the internal queue.^[600-developer__big-data__netty__netty-EventLoopGroup.md] The wrapper ensures that once the current task finishes, it triggers the scheduling of the next task in the queue.^[600-developer__big-data__netty__netty-EventLoopGroup.md] If no task is currently active, the system immediately polls the next task from the queue and passes it to the underlying executor to begin execution.^[600-developer__big-data__netty__netty-EventLoopGroup.md]
This mechanism creates a "serial" effect, ensuring tasks are processed one after another, effectively decoupling the execution order from the potentially parallel nature of the backing executor.^[600-developer__big-data__netty__netty-EventLoopGroup.md]
Code Example¶
class SerialExecutor implements Executor {
final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
final Executor executor;
Runnable active;
SerialExecutor(Executor executor) {
this.executor = executor;
}
public synchronized void execute(final Runnable r) {
tasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}
Related Concepts¶
- [[Thread Pool]]
- [[Concurrency]]
- [[Executor]]
Sources¶
^[600-developer__big-data__netty__netty-EventLoopGroup.md]