1

我有一个 Java 程序需要调用相同的外部可执行文件 6 次。这个可执行文件生成一个输出文件,一旦所有 6 次运行完成,我将这些文件“合并”在一起。我确实有一个 for 循环,我在其中运行代码,等待外部可执行文件的第一次运行结束,然后我再次调用它,等等。

我发现这非常耗时,平均需要 52.4 秒才能运行 6 次……我认为通过一次运行外部可执行文件 6 次来加速非常容易,尤其是因为它们不相互依赖. 我使用ExecutorServiceandRunnable等来实现这一点。

使用我当前的实现,我节省了大约 5 秒的时间,只快了大约 11%。

这是一些(简化的)代码,解释了我在做什么:

private final List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();

....

private void setUpThreadsAndRun() {
    ExecutorService executor = Executors.newFixedThreadPool(6);

    for (int i = 0; i < 6; i++) {
        //create the params object
       tasks.add(Executors.callable(new RunThread(params)));
    }

    try {
        executor.invokeAll(tasks);
    } catch (InterruptedException ex) {
        //uh-oh
    }

    executor.shutdown();
    System.out.println("Finished all threads!");
}

private class RunThread implements Runnable {
    public RunThread(ModelParams params) {
        this.params = params;
    }

    @Override
    public void run()
    {
         //NOTE: cmdarray is constructed from the params object
        ProcessBuilder pb = new ProcessBuilder(cmdarray);
         pb.directory(new File(location));
         p = pb.start();
    }
}

我希望有一种更有效的方法来做到这一点......或者我可能通过尝试一次运行此过程 6 次来“堵塞”我的计算机资源。这个过程确实涉及文件 I/O 并写入大小约为 30mb 的文件。

4

1 回答 1

2

只有当你有至少 6 个 CPU 内核并且你的应用程序受 CPU 限制——即主要执行处理器操作时,才能将可执行文件分叉 6 次才能获得性能提升。由于每个应用程序写入一个 30mb 的文件,听起来它正在执行大量的 IO,而应用程序是 IO 绑定的——受限于您的硬件服务 IO 请求的能力。

为了加快你的程序,你可以尝试 2 个并发进程,看看你是否得到了改进。但是,如果您的程序受 IO 限制,那么您将永远不会通过分叉多个副本来提高速度。

于 2012-05-09T14:13:20.907 回答