使用Java在循环内并行执行该方法

时间:2017-11-23 10:12:25

标签: java multithreading java-threads

我有如下代码。在循环中,它正在执行方法“process”。它按顺序运行。我想并行运行这个方法,但它应该在循环中完成,以便我可以在下一行中求和。即使它并行运行,所有函数都应该在第二个for循环执行之前完成。

如何在Jdk1.7中解决这个问题而不是JDK1.8版本?

public static void main(String s[]){
    int arrlen = 10;
    int arr[] = new int[arrlen] ;

    int t =0;
    for(int i=0;i<arrlen;i++){
        arr[i] = i;
        t = process(arr[i]);
        arr[i] = t;
    }

    int sum =0;
    for(int i=0;i<arrlen;i++){
        sum += arr[i];
    }
    System.out.println(sum);

}

public static int process(int arr){
    return arr*2;
}

2 个答案:

答案 0 :(得分:3)

以下示例可能会对您有所帮助。我使用fork / join框架来做到这一点。

对于像你的例子那样的小数组大小,传统的方法可能会更快,我怀疑fork / join方式会花费更多的时间。但是对于更大的大小或进程,fork / join框架是合适的。甚至java 8并行流也使用fork / join框架作为底层基础。

def response(message):
    return {
        "dialogAction":{
            "type":"Close",
            "fulfillmentState":"Fulfilled",
            "message":{
                "contentType":"PlainText",
                "content":message
            }
        }
    }

return response(str(logging_info_object))

您的主要课程如下所示

public class ForkMultiplier extends RecursiveAction {
        int[] array;
        int threshold = 3;
        int start;
        int end;

        public ForkMultiplier(int[] array,int start, int end) {
            this.array = array;
            this.start = start;
            this.end = end;
        }

        protected void compute() {
            if (end - start < threshold) {
                computeDirectly();
            } else {
                int middle = (end + start) / 2;
                ForkMultiplier f1= new ForkMultiplier(array, start, middle);
                ForkMultiplier f2= new ForkMultiplier(array, middle, end);
                invokeAll(f1, f2);
            }
        }

        protected void computeDirectly() {
            for (int i = start; i < end; i++) {
                array[i] = array[i] * 2;
            }
        }
    }

答案 1 :(得分:0)

你基本上需要使用自Java 1.5以来存在的Executors和Futures组合(见Java Documentation)。

在下面的示例中,我创建了一个主类,它使用另一个辅助类,其作用类似于要并行化的处理器。

主要课程分为3个步骤:

  1. 创建进程池并并行执行任务。
  2. 等待所有任务完成工作。
  3. 从任务中收集结果。
  4. 由于说明的原因,我已经放了一些日志,更重要的是,我在每个进程中放置了一个随机的等待时间'业务逻辑,模拟了一个由Process类运行的耗时算法

    每个进程的最长等待时间是2秒,这也是步骤2的最长等待时间,即使您增加了并行任务的数量(只需尝试将以下代码的变量totalTasks更改为测试它。)

    这里是主类:

    package com.example;
    
    import java.util.ArrayList;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class Main
    {
        public static void main(String[] args) throws InterruptedException, ExecutionException
        {
            int totalTasks = 100;
    
            ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(totalTasks);
    
            System.out.println("Step 1 - Starting parallel tasks");
    
            ArrayList<Future<Integer>> tasks = new ArrayList<Future<Integer>>();
            for (int i = 0; i < totalTasks; i++) {
                tasks.add(newFixedThreadPool.submit(new Process(i)));
            }
    
            long ts = System.currentTimeMillis();
            System.out.println("Step 2 - Wait for processes to finish...");
    
            boolean tasksCompleted;
            do {
                tasksCompleted = true;
    
                for (Future<Integer> task : tasks) {
                    if (!task.isDone()) {
                        tasksCompleted = false;
                        Thread.sleep(10);
                        break;
                    }
                }
    
            } while (!tasksCompleted);
    
            System.out.println(String.format("Step 2 - End in '%.3f' seconds", (System.currentTimeMillis() - ts) / 1000.0));
    
            System.out.println("Step 3 - All processes finished to run, let's collect results...");
    
            Integer sum = 0;
    
            for (Future<Integer> task : tasks) {
                sum += task.get();
            }
    
            System.out.println(String.format("Total final sum is: %d", sum));
        }
    }
    

    这里是Process类:

    package com.example;
    
    import java.util.concurrent.Callable;
    
    public class Process implements Callable<Integer>
    {
        private Integer value;
    
        public Process(Integer value)
        {
            this.value = value;
        }
    
        public Integer call() throws Exception
        {
            Long sleepTime = (long)(Math.random() * 2000);
    
            System.out.println(String.format("Starting process with value %d, sleep time %d", this.value, sleepTime));
    
            Thread.sleep(sleepTime);
    
            System.out.println(String.format("Stopping process with value %d", this.value));
    
            return value * 2;
        }
    }
    

    希望这有帮助。