使用多线程并行化 Java 中的 for 循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43655768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 07:38:43  来源:igfitidea点击:

Parallellize a for loop in Java using multi-threading

javamultithreadingparallel-processingthreadpool

提问by Jhutan Debnath

I am very new to java and I want to parallelize a nested for loop using executor service or using any other method in java. I want to create some fixed number of threads so that CPU is not completely acquired by threads.

我对 java 很陌生,我想使用执行程序服务或使用 java 中的任何其他方法并行化嵌套的 for 循环。我想创建一些固定数量的线程,以便线程不会完全获取 CPU。

    for(SellerNames sellerNames : sellerDataList) {
        for(String selleName : sellerNames) {
        //getSellerAddress(sellerName)
        //parallize this task
        }
    }

size of sellerDataList = 1000 and size of sellerNames = 5000.

SellerDataList 的大小 = 1000,sellerNames 的大小 = 5000。

Now I want to create 10 threads and assign equal chunk of task to each thread equally. That is for i'th sellerDataList, first thread should get address for 500 names, second thread should get address for next 500 names and so on.
What is the best way to do this job?

现在我想创建 10 个线程并为每个线程平均分配相同的任务块。那是对于第 i 个 SellerDataList,第一个线程应该获取 500 个名称的地址,第二个线程应该获取接下来 500 个名称的地址,依此类推。
完成这项工作的最佳方法是什么?

回答by Tamas Rev

There are two ways to make it run parallelly: Streams and Executors.

有两种方法可以让它并行运行:Streams 和 Executors。

Using streams

使用流

You can use parallel streams and leave the rest to the jvm. In this case you don't have too much control over what happens when. On the other hand your code will be easy to read and maintain:

您可以使用并行流并将其余部分留给 jvm。在这种情况下,您对何时发生的事情没有太多控制权。另一方面,您的代码将易于阅读和维护:

    sellerDataList.stream().forEach(sellerNames -> {
        Stream<String> stream = StreamSupport.stream(sellerNames.spliterator(), true); // true means use parallel stream
        stream.forEach(sellerName -> {
            getSellerAddress(sellerName);
        });
    });

Using an ExecutorService

使用 ExecutorService

Suppose, you want 5 Threads and you want to be able to wait until task completion. Then you can use a fixed thread pool with 5 threads and use Future-s so you can wait until they are done.

假设,您需要 5 个线程并且您希望能够等到任务完成。然后您可以使用具有 5 个线程的固定线程池并使用Future-s 以便您可以等到它们完成。

    final ExecutorService executor = Executors.newFixedThreadPool(5); // it's just an arbitrary number
    final List<Future<?>> futures = new ArrayList<>();
    for (SellerNames sellerNames : sellerDataList) {
        for (final String sellerName : sellerNames) {
            Future<?> future = executor.submit(() -> {
                getSellerAddress(sellerName);
            });
            futures.add(future);
        }
    }
    try {
        for (Future<?> future : futures) {
            future.get(); // do anything you need, e.g. isDone(), ...
        }
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }