如何知道CompletionService何时完成交付结果? [英] How to know when a CompletionService is finished delivering results?

查看:471
本文介绍了如何知道CompletionService何时完成交付结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用CompletionService处理一系列线程完成后的结果.我有一个循环的服务,以获取其提供的Future对象(当它们可用时),但是我不知道确定所有线程何时完成(从而退出循环)的最佳方法:

I want to use a CompletionService to process the results from a series of threads as they are completed. I have the service in a loop to take the Future objects it provides as they become available, but I don't know the best way to determine when all the threads have completed (and thus to exit the loop):

import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

public class Bar {

    final static int MAX_THREADS = 4;
    final static int TOTAL_THREADS = 20;

    public static void main(String[] args) throws Exception{

        final ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(MAX_THREADS);
        final CompletionService<Integer> service = new ExecutorCompletionService<Integer>(threadPool);

        for (int i=0; i<TOTAL_THREADS; i++){
            service.submit(new MyCallable(i));
        }

        int finished = 0;
        Future<Integer> future = null;
        do{
            future = service.take();
            int result = future.get();
            System.out.println("  took: " + result);
            finished++;             

        }while(finished < TOTAL_THREADS);

        System.out.println("Shutting down");
        threadPool.shutdown();
    }


    public static class MyCallable implements Callable<Integer>{

        final int id;

        public MyCallable(int id){
            this.id = id;
            System.out.println("Submitting: " + id);
        }

        @Override
        public Integer call() throws Exception {
            Thread.sleep(1000);
            System.out.println("finished: " + id);
            return id;
        }
    }
}

我已经尝试检查ThreadPoolExecutor的状态,但是我知道getCompletedTaskCount和getTaskCount方法只是近似值,不应被依赖.有没有比我自己计算它们更好的方法来确保我从CompletionService中检索了所有期货?

I've tried checking the state of the ThreadPoolExecutor, but I know the getCompletedTaskCount and getTaskCount methods are only approximations and shouldn't be relied upon. Is there a better way to ensure that I've retrieved all the Futures from the CompletionService than counting them myself?

Nobeh提供的链接和此链接都建议计算提交的任务数,然后调用take()多次是要走的路.令我惊讶的是,没有办法询问CompletionService或其执行器还剩下什么.

Both the link that Nobeh provided, and this link suggest that counting the number of tasks submitted, then calling take() that many times, is the way to go. I'm just surprised there isn't a way to ask the CompletionService or its Executor what's left to be returned.

推荐答案

回答这些问题将为您提供答案?

Answering to these questions gives you the answer?

  • 您的异步任务会创建提交给CompletionService的其他任务吗?
  • service是唯一应该处理您的应用程序中创建的任务的对象吗?
  • Do your asynchronous tasks create other tasks submitted to CompletionService?
  • Is service the only object that is supposed to handle the tasks created in your application?

基于参考文档CompletionService根据消费者/生产者方法起作用,并利用内部Executor.因此,只要您在一个位置生成任务并在另一位置使用它们,CompletionService.take()就会表示是否还有其他结果要提供.

Based on reference documentation, CompletionService acts upon a consumer/producer approach and takes advantage of an internal Executor. So, as long as, you produce the tasks in one place and consume them in another place, CompletionService.take() will denote if there are any more results to give out.

我相信此问题也可以为您提供帮助

I believe this question also helps you.

这篇关于如何知道CompletionService何时完成交付结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆