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);
}
}
Yes, the order is preserved. From the javadocs
Delayed tasks execute no sooner than they are enabled, but without any real-time guarantees about when, after they are enabled, they will commence. Tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission.
You can see this in action too
public static void main(String args[]) {
ScheduledExecutorService e = Executors.newScheduledThreadPool(1);
e.schedule(delay("delay for 1 second", 10), 1, TimeUnit.SECONDS);
e.schedule(delay("delay for 5 second", 0), 5, TimeUnit.SECONDS);
e.schedule(delay("delay for 3 second", 0), 3, TimeUnit.SECONDS);
e.schedule(delay("delay for 7 second", 0), 7, TimeUnit.SECONDS);
e.schedule(delay("delay for 2 second", 0), 2, TimeUnit.SECONDS);
}
private static Runnable delay(String message, int initialDelay) {
return () -> {
Thread.sleep(initialDelay);
System.out.println(message);
};
}
prints
delay for 1 second
delay for 2 second
delay for 3 second
delay for 5 second
delay for 7 second
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.