Serial execution of the java executor service

I use the Executor structure specifically Executors.newCachedThreadPool();
I have a Runnable list, for example. 100.
The first 50 each creates a value (stored in the list) that should be used by the last 50.
I thought that if I pass Runnable to executor.execute() in the order in which they are in the list, they will also be executed in the same order.
But this does not happen. Tasks seem to run randomly, and they alternate, rather than run sequentially.
Is this supposed to work? Any way around this problem?

thanks

+3
source share
3 answers

You need to send tasks in two batches or create an explicit β€œhappen sooner” relationship. Offer to create two batches of tasks and using invokeAll(batch1); invokeAll(batch2); invokeAll(batch1); invokeAll(batch2); The invokeAll() method invokeAll() complete all tasks and lock them until completion. You may need to wrap Runnable as Callable s, which you can do with Executors.callable(Runnable r) . (@Cameron Skinner beat me to get sample code, see this answer for more ...)

The whole point of the performers is to abstract from the specifics of the performance, so ordering is not guaranteed unless explicitly stated. If you want strictly sequential execution, do it in the thread you are working in (the simplest), do it in a single-threaded executor, ala Executors.newSingleThreadExecutor() or explicitly synchronize tasks. If you want to do the latter, you can use a barrier or latch and block dependent tasks on the barrier / latch. You can also implement the first block of Callable tasks, return Future and call the dependent tasks myFuture.get() , which would force them to block until the results are returned.

If you say more about your specific application, we can help more specifically.

+10
source

This is the correct behavior. You have no guarantee what order Runnables runs.

Artists work in parallel, while it seems that you want tasks to be performed in sequential order. You can either send the first 50 tasks, wait for their completion, and then send the second 50 tasks or (if the order of execution is important), just run them all in one thread.

For instance,

 for (Future<Whatever> f: service.invokeAll(first50tasks)) { addResultToList(f.get()); } Future<Whatever> output = service.invokeAll(second50tasks); 
+7
source

Perhaps you could execute first 50, shutdown and awaitTermination , and only then execute remaining 50? See this answer for sample code.

+2
source

Source: https://habr.com/ru/post/1346168/


All Articles