并行化for循环

RIc*_*ams 25 java multithreading for-loop

我有一个for循环,其中迭代计算i不依赖于前一次迭代中完成的计算.

我想并行化for循环(我的代码在java中),以便多个迭代的计算可以在多个处理器上同时运行.我应该为每次迭代的计算创建一个线程,即要创建的线程数等于迭代次数(for循环中的迭代次数是多少)?这该怎么做?

Whi*_*g34 46

这是一个小例子,您可能会发现有助于开始并行化.它假定:

  1. 您创建一个Input对象,其中包含计算的每次迭代的输入.
  2. 您创建一个Output对象,其中包含计算每次迭代输入的输出.
  3. 您希望传入输入列表并一次性获取所有输出列表.
  4. 您的输入是一项合理的工作,因此开销不会太高.

如果您的计算非常简单,那么您可能需要考虑批量处理它们.你可以通过在每个输入中输入100来做到这一点.它使用与系统中的处理器一样多的线程.如果您正在处理纯粹的CPU密集型任务,那么这可能就是您想要的数字.如果他们被阻塞等待其他东西(磁盘,网络,数据库等),你会想要更高

public List<Output> processInputs(List<Input> inputs)
        throws InterruptedException, ExecutionException {

    int threads = Runtime.getRuntime().availableProcessors();
    ExecutorService service = Executors.newFixedThreadPool(threads);

    List<Future<Output>> futures = new ArrayList<Future<Output>>();
    for (final Input input : inputs) {
        Callable<Output> callable = new Callable<Output>() {
            public Output call() throws Exception {
                Output output = new Output();
                // process your input here and compute the output
                return output;
            }
        };
        futures.add(service.submit(callable));
    }

    service.shutdown();

    List<Output> outputs = new ArrayList<Output>();
    for (Future<Output> future : futures) {
        outputs.add(future.get());
    }
    return outputs;
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*rdt 10

您不应手动执行线程处理.代替:

  • 创建一个合理大小的线程池执行程序服务(如果您的计算没有IO,请使用与核心一样多的线程).
  • 运行一个循环,将每个单独的计算提交给执行程序服务并保留结果Future对象.请注意,如果每个计算只包含少量工作,这将产生大量开销,甚至可能比单线程程序慢.在这种情况下,提交执行mdma建议的计算数据包的作业.
  • 运行第二个循环,收集所有Futures 的结果(它将隐式等待,直到所有计算完成)
  • 关闭执行程序服务