有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

要在java中使用多线程并行化嵌套for循环吗

我想使用executor服务或java中的任何其他方法并行化嵌套for循环。我想创建一些固定数量的线程,这样CPU就不会完全被线程获取。这里的每个线程都在做一些独立的工作。第一个线程应该执行j=0,20,30,40第二个线程应该执行j=1,21,31,41每个线程应该并行执行。这就是我想做的

ExecutorService service = Executors.newFixedThreadPool(NoOfThreads);
  for(int i = 0; i < 100; i++) {
    for(int j=0; j < 50000000; j++) {
      //some independent work
      //parallelize this work
    ...

这就是我所做的

for (int i = 0; i < 100; i++) {
  ExecutorService executorService = Executors.newFixedThreadPool(20);
  for (int j=0; j < 50000000; j++) {
    executorService.execute(new Runnable() {
      @Override
      public void run() {
        //do some work
        //send data to some api
      }});
  }
  executorService.shutdown();
  while (!executorService.isTerminated()) {
    System.out.print("");
  }
}

我想确保这是我想要做的事情的正确实现。请让我知道如何改进我的代码


共 (2) 个答案

  1. # 1 楼答案

    这里有两个明显的问题:

     while (!executorService.isTerminated()) {
       System.out.print("");
     }
    

    这意味着调用此代码的main线程将执行hot等待。你应该做一个线程。在这里打电话;为了避免毫无理由地消耗无数的CPU周期

    但没什么大不了的;因为你的代码在这里

    for (int i = 0; i < 100; i++) {
      ExecutorService executorService = Executors.newFixedThreadPool(20);
    

    创建100*20个线程;完成5000万项你打算推进的任务。也许我错了;但我有一种直觉,这将推动大多数系统超越它们的极限

    导致:从结构上来说,这不是一个好方法。创建该服务;增加任务,;任务内容本身是不同的

    从这个意义上说:

    • 您希望创建一个执行器服务(使用一些线程,这些线程在某种程度上类似于底层硬件的功能)
    • 您希望将数量较小的任务推入该区域

    意思是:当您必须处理一百万个元素时,您不会创建一百万个任务。你可以创建1000个任务;每一个可以工作1000个元素

  2. # 2 楼答案

    您的代码分配50000000个可运行对象,这将很慢。 相反,每个工作线程应该运行一个循环,获取下一个要处理的“j”值。使用AtomicInteger确保每个“j”值只处理一次

    下面是一些概要代码:

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class ParallelLoop {
        public static void main(String[] args) throws InterruptedException {
    
            for (int i = 0; i < 10; i++) {
                final int n = 50000000;
                final AtomicInteger atomicJ = new AtomicInteger();
    
                int nThread = 20;
                ExecutorService es = Executors.newFixedThreadPool(nThread);
                for (int t = 0; t < nThread; t++) {
                    Runnable r = new Runnable() {
                        public void run() {
                            while (true) {
                                int j = atomicJ.getAndIncrement();
                                if (j >= n)
                                    return;
                                // Process J ....
                            }
                        }
                    };
                    es.submit(r);
                }
                es.shutdown();
                es.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
                System.out.println("====");
            }
        }
    
    }