Skip to content

Instantly share code, notes, and snippets.

@renzihui
Created December 20, 2021 10:57
Show Gist options
  • Select an option

  • Save renzihui/211ba8e38d0ebcf0d130a1ba7ec44658 to your computer and use it in GitHub Desktop.

Select an option

Save renzihui/211ba8e38d0ebcf0d130a1ba7ec44658 to your computer and use it in GitHub Desktop.
An Executor only runs one task at a time.
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.Executor;
/**
* An Executor only runs one task at a time.
*/
public class SequentialExecutor implements Executor {
private final Executor delegate;
private final Deque<Runnable> jobs = new ArrayDeque<>();
private boolean executing = false;
private Object lock = new Object();
public SequentialExecutor(Executor delegate) {
this.delegate = delegate;
}
@Override
public void execute(Runnable command) {
synchronized (lock) {
jobs.addLast(command);
if (!executing) {
poll();
}
}
}
/**
* poll should always be guarded by synchronization on lock
*/
private void poll() {
if (jobs.isEmpty()) {
return;
}
Runnable runnable = jobs.removeFirst();
executing = true;
delegate.execute(() -> run(runnable));
}
private void run(Runnable runnable) {
try {
runnable.run();
} finally {
synchronized (lock) {
executing = false;
poll();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment