Home > Software engineering >  How to get the completed task on Executor Service till some time?
How to get the completed task on Executor Service till some time?

Time:12-02

I want to retrieve the results for the threads that have completed their task and retrieve the result and ignore other threads. My aim is to do something like this.

public class Main {
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(16);

        for(int i = 0 ; i < 100 ; i  ) {
            service.submit(threadClass);
            // some thread that generates result in 5 seconds say
        }
        
        // Main thread does some work here that takes time


        /*
        The task that has finished till this point should be taken
        Let's say 7 results are generated till this point,
        So get the 7 results and stop other threads
        Want result like a List<Integer>
        */

        

        service.shutdownNow(); // stop all other threads
          

    }

}


CodePudding user response:

You can use a CompletionService, a blocking queue is used internally, and the "completed" Future will be put into this queue, so you can call queue#poll to get all finish Future. :

        ExecutorService service = Executors.newFixedThreadPool(16);
        CompletionService<Integer> completionService = new ExecutorCompletionService<>(service);
        for(int i = 0 ; i < 100 ; i  ) {
            completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Random random = new Random();
                    int nextInt = random.nextInt(10000);
                    System.out.println("I will take "   nextInt   " ms to finish");
                    try {
                        Thread.sleep(nextInt);
                    } catch (InterruptedException e) {
                        System.out.println("I am interrupt");
                        return -1;
                    }
                    System.out.println("I am finish");
                    return nextInt;
                }
            });
        }
        // do other work
        Thread.sleep(5000);
        List<Integer> completeResult = new ArrayList<>();
        Future<Integer> future;
        while ((future = completionService.poll()) != null) {
            try {
                completeResult.add(future.get());
            } catch (Exception exception) {
                // exception
            }
        }
        service.shutdownNow();
        System.out.println(completeResult);

CodePudding user response:

ExecutorService.submit returns a Future that can be used to wait for completion and get the result.

There is a version of get that has a timeout, this is useful for polling for completion.

You should collect the Futures and use them. Keep an array of 100 Futures, then when required, loop over them collecting results until you have enough results for your needs.

  • Related