如何识别管道中的所有任务何时在单个Java Executor Service中完成

时间:2012-10-17 10:31:16

标签: java concurrency java-7 executorservice java.util.concurrent

我有一系列要对文件执行的任务,每种不同类型的任务都在不同的执行程序服务中运行。在初始化每个执行程序服务后,我启动第一个任务,这保证在完成处理所有文件之前不会完成,因为它处理文件夹要么不再需要工作,要么向service2提交可调用任务。因此,当对第一个任务的shutdown()调用成功时,现在将在task2中处理所有文件,或者在pipleline中进一步处理另一个任务,依此类推。当我们关闭最终服务时,我们就完成了。

Loader loader = Loader.getInstanceOf();
List<ExecutorService> services = new ArrayList<ExecutorService>();
ExecutorService es = Executors.newSingleThreadExecutor();

//Init Services
services.add(es);
services.add(task1.getService());
services.add(task2.getService());
services.add(task3.getService());
services.add(task4.getService());

//Start Loading Files
es.submit(loader);

int count = 0;
for (ExecutorService service : services)
{
    service.shutdown();
    count++;
    //Now wait for all submitted tasks to complete, for upto one day per task
    service.awaitTermination(10, TimeUnit.DAYS);
    MainWindow.logger.severe("Shutdown Task:" + count);
}

public class AnalyserService
{
    protected String threadGroup;
    public AnalyserService(String threadGroup)
    {
        this.threadGroup=threadGroup;
    }

    protected  ExecutorService      executorService;
    protected  CompletionService    completionService;

    protected void initExecutorService()
    {
        int workerSize = Runtime.getRuntime().availableProcessors();
        executorService
                = Executors.newFixedThreadPool(workerSize, new SongKongThreadFactory(threadGroup));
    }

    public ExecutorService getService()
    {
        if (executorService == null || executorService.isShutdown())
        {
            initExecutorService();
        }
        return executorService;
    }
}

所以这一切都正常除了我的cpu加载逻辑不正确。每个服务使用的池数等于计算机的cpu数。因此,如果计算机有4个cpus并且我们有5个服务,那么我们可以有20个线程都在尝试同时重载cpus。我想在这种情况下我一次只能有4个线程。

如果我限制每个服务使用一个线程,那么Id只有5个线程同时运行,但这仍然是正确的,因为

  1. 如果有更多服务或更多cpus
  2. ,将不再是正确的
  3. 效率低下,因为大部分工作的pipleline踢将由task1完成,如果我将它限制为一个cpu它将比必要的慢,稍后对话大多数线程将由后续任务和task1完成将无所事事。
  4. 我认为我需要的是所有任务共享一个执行程序服务,并将其poolize设置为等于计算机的cput数。 但接下来我将如何确定服务何时完成?

    我正在使用Java 7,因此Java 7中有任何新内容可能有所帮助,目前仅使用Java 5并发功能

1 个答案:

答案 0 :(得分:-1)

你问题的核心是:“[...]重载cpu。” 如果这是问题,只需正确安排应用程序的优先级。顺便说一句,您更有可能增加IO负载而不是增加CPU负载;许多不同的线程实际上是一件好事: - )

但是,您的问题是:“但那我该如何确定服务何时完成?” 非常简单的答案:submit()而不是invokeAll()并检查您收到的isDone()对象的Future方法。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable