I have a ScheduledExecutorService
that has a pool size of 1
threads.
If I schedule many tasks using that service with the same delay, is the order of scheduling preserved during the execution?
Yes, as long as the scheduler implementation used will follow the interface specification. For example, new ScheduledThreadPoolExecutor(1)
will use a DelayedWorkQueue
which will preserve the order.
As per javadoc all ScheduledExecutorService
implementations should preserve order:
Tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission.
One can test the implementation with the example below:
import com.google.code.tempusfugit.concurrency.IntermittentTestRunner;
import com.google.code.tempusfugit.concurrency.annotations.Intermittent;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(IntermittentTestRunner.class)
public class ScheduledExecutorServiceTest {
@Test
@Intermittent(repetition = 20)
public void preservesOrderOfTasksScheduledWithSameDelay() throws InterruptedException {
ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
AtomicInteger atomicInteger = new AtomicInteger(0);
int numTasks = 1_000;
CountDownLatch countDownLatch = new CountDownLatch(numTasks);
for (int i = 0; i < numTasks; i++) {
int finalI = i;
scheduledExecutorService.schedule(() -> {
atomicInteger.compareAndSet(finalI, finalI + 1);
countDownLatch.countDown();
}, 10, TimeUnit.MILLISECONDS);
}
countDownLatch.await();
assertThat(atomicInteger.get()).isEqualTo(numTasks);
}
}