SerialExecutor implements Executor { @Override public void execute(@Nullable final Runnable runnable) { if (runnable == null) { return; } Runnable wrapped = new Runnable() { @Override public void run() { try { runnable.run(); } finally { next(); } } }; synchronized (runnables) { runnables.offer(wrapped); if (!isExecuting) { next(); } } } SerialExecutor(@NonNull Executor executor); @Override void execute(@Nullable final Runnable runnable);  }
@Test public void testOrder() throws InterruptedException { final List<Integer> actual = new ArrayList<>(); final List<Integer> expected = new ArrayList<>(); final CountDownLatch latch = new CountDownLatch(100); for (int i = 1; i <= 100; i++) { final int count = i; expected.add(count); executor.execute(new Runnable() { @Override public void run() { actual.add(count); latch.countDown(); } }); } latch.await(); assertEquals(expected, actual); }