Executor interface in java.util.concurrent package lets you submit Runnable tasks. Executor then handles the execution of the task. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc.
Contract of Executor interface has a single method: execute(Runnable command)
This implementation uses another Executor to run the tasks. It maintains a queue for managing tasks. It guarantees that there is only one task running at a time.
public class SerialExecutor implements Executor {
private Executor executor;
private Queue<Runnable> taskQueue = new LinkedList<>();
private Runnable active = null;
public static void main(String[] args) {
Executor executor = new SerialExecutor(Executors.newFixedThreadPool(5));
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Task completed!");
}
});
}
public SerialExecutor(Executor executor) {
this.executor = executor;
}
@Override
public void execute(Runnable command) {
taskQueue.offer(new Runnable() {
@Override
public void run() {
try {
command.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
private void scheduleNext() {
if ((active = taskQueue.poll()) != null) {
executor.execute(active);
}
}
}