Created
December 20, 2021 10:57
-
-
Save renzihui/211ba8e38d0ebcf0d130a1ba7ec44658 to your computer and use it in GitHub Desktop.
An Executor only runs one task at a time.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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