mpb
mpb

Reputation: 83

ExecutorService execute runnable in serial order

I'm using executor service with newSingleThreadExecutor to execute my Runnable task in serial order, however seems to be serial execution order is not guaranteed, as sometime tasks are executed in random order.

executorService =  Executors.newSingleThreadExecutor();
executorService.submit(MyTask1);
executorService.submit(MyTask2);

MyTask performs some Asynchronous operation and send the result back to the class from where I'm executing the task.

though docs says, with newSingleThreadExecutor () tasks has to be executed serially,Im not able to find out what I'm missing here.any help would be appreciated.

Thanks

Upvotes: 3

Views: 3380

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 340118

tl;dr

If the results you are watching arrive out-of-order are being produced asynchronously, then all is well. Async work is being done on its own separate timeline. By definition, the async work launched by task # 1 may not complete until long after tasks # 1, 2, & 3 are all done (for example).

Asynchronous means “don’t wait for me”

You mentioned:

MyTask performs some Asynchronous operation

Asynchronous execution means the calling code need not wait for the async operation to complete.

The calling code, your task submitted to the executor service, makes the request for async work to be done, and the task immediately continues. If that task has no further work, the task is complete. So the executor service can move on.

The executor service moves on. The executor service executes the second submitted task. Meanwhile, the async work requested above may not yet be done. Perhaps the async work is waiting on a resource such waiting for a call over the network to return, or the async work is waiting for a database query to execute. That, by definition of asynchronous, does not block the task submitted to the executor. The executor service is now running the 2nd submitted task, and may be a third or fourth, before, finally, your async work completes.

diagram of a series of submitted tasks being executed sequentially along a timeline with separate async work being done in parallel along several tasks after being spawned from the first task

Feature, not a bug

In other words, a feature, not a bug. The ExecutorService returned by Executors.newSingleThreadExecutor() fulfilled its promise that “Tasks are guaranteed to execute sequentially”. The fact that as a by-product one of those tasks spins off async work does not change the fact that the tasks as submitted were indeed executed in their sequential order.

Upvotes: 3

Bohemian
Bohemian

Reputation: 425358

Since execution order is guaranteed to be sequential, you are problably not using a single thread executor in the code you are actually running.

As a work around, submit one task that does two things:

executorService.submit(() -> {MyTask1.run(); MyTask2.run();});

Upvotes: 3

Related Questions