I am trying to build an implementation of the ExecutorService
, let\'s call it SequentialPooledExecutor
, with the following properties.
Recently I encountered the same problem. There is no built-in class for this, but a queue is close enough. My simple implementation looks like this (maybe it's helpful for others looking for examples on the same issue)
public class SerializedAsyncRunnerSimple implements Runnable {
private final ExecutorService pool;
protected final LinkedBlockingQueue queue = new LinkedBlockingQueue<>(); //thread safe queue
protected final AtomicBoolean active = new AtomicBoolean(false);
public SerializedAsyncRunnerSimple(ExecutorService threadPool) {this.pool = threadPool;}
public void addWork(Runnable r){
queue.add(r);
startExecutionIfInactive();
}
private void startExecutionIfInactive() {
if(active.compareAndSet(false, true)) {
pool.execute(this);
}
}
@Override
public synchronized void run() {
while(!queue.isEmpty()){
queue.poll().run();
}
active.set(false); //all future adds will not be executed on this thread anymore
if(!queue.isEmpty()) { //if some items were added to the queue after the last queue.poll
startExecutionIfInactive();// trigger an execution on next thread
}
}