首页 文章

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

提问于
浏览
1

我有一系列要在文件上完成的任务,每个不同类型的任务都在不同的 Actuator 服务中运行 . 在初始化每个执行程序服务后,我启动第一个任务,这保证在完成处理所有文件之前不会完成,因为它处理文件夹要么不再需要工作,要么向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;
    }
}

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

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

  • 如果有更多服务或更多cpu,将不再是正确的

  • 效率低下,因为大部分工作的pipleline踢将由task1完成,如果我将它限制为一个cpu它将比必要的慢,稍后转换大多数线程将由后续任务完成,task1将具有没事做 .

我认为我需要的是所有任务共享一个 Actuator 服务,并将其池大小设置为等于计算机的cput数 . But then how am I going to identify when the service has finished

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

1 回答

  • -1

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

    但是,您的问题是:" But then how am I going to identify when the service has finished ? "非常简单的答案: submit() 而不是 invokeAll() 并检查您收到的 Future 对象的 isDone() 方法 .

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

相关问题