简体   繁体   中英

How to get the completed task on Executor Service till some time?

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
          

    }

}


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);

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.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM