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

Jhu*_*ath 6 java parallel-processing multithreading threadpool

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

    for(SellerNames sellerNames : sellerDataList) {
        for(String selleName : sellerNames) {
        //getSellerAddress(sellerName)
        //parallize this task
        }
    }
Run Code Online (Sandbox Code Playgroud)

sellerDataList = 1000的大小和sellerNames = 5000的大小.

现在我想创建10个线程并将相同的任务块分配给每个线程.这是为了我的sellerDataList,第一个线程应该获得500个名称的地址,第二个线程应该获得下一个500个名称的地址,依此类推.
做这份工作的最佳方法是什么?

Tam*_*Rev 13

有两种方法可以使它并行运行:Streams和Executors.

使用流

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

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

使用ExecutorService

假设您需要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();
    }
Run Code Online (Sandbox Code Playgroud)

  • 现在在Java 8中可以执行`sellerNames.parallelStream()。forEach(...)` (2认同)