Java using invokeAll to get future results in order, but only for some threads

I ... really don't know how to better formulate the name. But basically, I have a thread pool with all of these threads that work. I want them to report their results in the order in which they were appointed, but at the same time I want to work in parties. For illustration and example, there will be

ExecutorService exec = Executors.newFixedThreadPool(8); class MyCallable implements Callable<byte[]> { private final int threadnumber; MyCallable(int threadnumber){ this.threadnumber = threadnumber; } public byte[] call() { //does something } } List<Callable<byte[]>> callables = new ArrayList<Callable<byte[]>>(); for(int i=1; i<=20; i++) { callables.add(new MyCallable(i)); } try { List<Future<byte[]>> results = exec.invokeAll(callables); for(Future<byte[]> result: results) { System.out.write(result.get(), 0, result.get().length); } 

Basically, a pool thread has 8 threads, and as a result I have 20 tasks (these are just examples). The way it works now, if I understand correctly, is that it waits until all 20 tasks are completed before they are displayed in order (from 1 to 20). It is assumed that this program should output a continuous stream of bytes (which were processed by the streams, and since I need to keep the order intact, I used the future interface). Although I do not mind waiting until all 20 tasks are completed, there is one way or another so that the threads are simply displayed in order when they go.

If there is no way, or I just do not completely understand how invokeAll works, clarification is also welcome. Thanks for the bunch in advance! The performers are a little confused since I just found out about them.

Random addition, am I even allowed to return an array of bytes from the called?

+4
source share
2 answers

invokeAll() waits until all results are computed before they are returned.

Use a loop and submit() them one by one, this method immediately returns the Future with the expected result:

 ... for(int i=1; i<=20; i++) { results.add(exec.submit(new MyCallable(i))); } try { for(Future<Integer> result: results) { System.out.write(result.get(), 0, result.get().length); } } ... 
+5
source

With invokeAll you can also achieve.

  List<Future<byte[]>> results = exec.invokeAll(callables); 

It will return a list of future objects.

ThreadPoll will execute the tasks in random order. The task execution order cannot be monitored.

Future object

  • His link to the task, which is presented in ThreadPool.

  • It has a get () method. Its a call blocking method. If you call the get () method, the call will wait until the tasks are completed.

How to ensure the order of sending tasks

The order of the results is the same in the order of treatment. Even the thread pool will execute in a different order, which we can get in the same order.

For example

Three tasks 1,2,3

1 and 3 → Completed.

2 ------> Takes a lot of time.

After calling invokeAll, it will return a list of the future in the same order.

Task 1: Future # get returns the result of the return from the moment it is completed

Task 2: the future # get method waits for the task to complete.

The iteration awaits the completion of the second task, although the third task is completed. He will not receive a result from the third stream.

0
source

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


All Articles