2017-11-23 11 views
3

私は以下のようなコードを持っています。ループでは、 "process"というメソッドを実行しています。これは順次実行されています。このメソッドを並列に実行したいのですが、次の行で合計できるようにループ内で終了する必要があります。つまり、2番目のforループが実行される前にすべての関数が終了するはずです。 誰もJDK1.8versionではなくJdk1.7で解決する方法を手助けできますか?javaを使用してループ内で並列にメソッドを実行する

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; 
} 
+0

Java fork/joinフレームワークの助けを得ることができます。これはJava7の一部です .https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html –

+0

また、wait()およびnotify()メソッドを調べることもできます –

答えて

3

以下は例です。私はそれを行うためにフレームワーク/フォークを使用しました。

例のような小さな配列サイズの場合、従来の方法が高速になる可能性があり、フォーク/結合方法が少し時間がかかるとは思われません。しかし、より大きなサイズやプロセスでは、fork/joinフレームワークが適しています。 Java 8の並列ストリームであっても、基盤となるfork/joinフレームワークを使用します。

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; 
      } 
     } 
    } 

あなたは、メインクラスは、あなたは基本的にJavaの1.5(Java Documentationを参照)ので、存在して組み合わせるexecutorおよび先物を使用する必要が

public static void main(String s[]){ 

     int arrlen = 10; 
     int arr[] = new int[arrlen] ; 


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

     ForkJoinPool pool = new ForkJoinPool(); 
     pool.invoke(new ForkMultiplier(arr, 0, arr.length)); 

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

     System.out.println(sum); 

    } 
0

の下にこれをしたいと思います。

次の例では、並列化するプロセッサのように動作する別のヘルパークラスを使用するメインクラスを作成しました。

メインクラスは、3つのステップに分割される:

  1. 、プロセスプールを作成し、並行して作業を実行します。
  2. すべてのタスクが完了するのを待ちます。
  3. タスクから結果を収集します。教訓的な理由から

が、私はいくつかのログを入れて、より重要ましたが、私は、Processクラスによって、時間のかかるアルゴリズムのRANをシミュレートし、各プロセスのビジネスロジックでランダムな待ち時間を入れています。

並列タスクの数を増やした場合でも、各プロセスの最大待機時間は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; 
    } 
} 

・ホープ、このことができます。

関連する問題