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

时间:2017-04-27 09:26:44

标签: java multithreading parallel-processing nested-loops

我想使用执行器服务或使用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 个答案:

答案 0 :(得分:0)

嗯,这里有两个明显的问题:

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

意味着您调用此代码的主题将执行等待。你应该在这里做一个Thread.sleep()调用;绝对没有理由避免浪费数以万计的CPU周期。

但并不重要;因为你的代码在这里

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

创建100 * 20个线程;处理您打算推入的50000000个任务。也许我错了;但我有一种直觉感觉会使大多数系统超出其极限。

导致:在结构上,这不是一个好方法。创建该服务;并添加任务;而任务内容本身就是不同的东西。

从这个意义上说:

  • 您想要创建一个执行程序服务(使用多个类似于底层硬件功能的线程)
  • 您希望将较小数量的任务推送到

含义:当您需要处理100万个元素时,您不会创建100万个任务。你可以创建1000个任务;每个人都有1000个元素。

答案 1 :(得分:0)

您的代码会分配50000000个Runnable对象,这将会很慢。 相反,每个工作线程都应该运行一个循环来获取下一个&#34; j&#34;要处理的价值。使用AtomicInteger确保每个&#34; j&#34;值只处理一次。

以下是一些大纲代码:

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("====");
        }
    }

}