2016-03-24 17 views
1

私は、ユーザー入力を介して複数のスレッド上の行列の計算を分割して1にすることができるスレッドシステム(マスタースレーブ)で配列を使用するソリューションを探しています主なスレッドをマトリックスの1フィールドを計算する複数のスレーブスレッドに割り当てる。配列(分割)のJavaマルチスレッド

私は自分の知識を使用しようとしましたが、方法の問題を転送しています。 コードは機能しますが、同時にすべてのスレッドではなく、1つのスレッドのみを使用します。

私は行列を何とか分けることができました(これはSpliteratorですか?)しかし、正確には分かりません。

結果フィールドが空の場合でもブーリアンを使用しようとしましたが、実際には全く機能しません。

import java.io.BufferedReader; 
import java.io.File; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.util.Arrays; 
import java.util.Scanner; 

class Threadverteiler extends Thread { 

public Threadverteiler(Thread[] threads) { 
    synchronisiert(threads); 
} 

public void synchronisiert(Thread[] t) { 

    Thread[] threads = t; 
    synchronized (threads) { 
     for (int i = 0; i < threads.length; i++) { 

      threads[i].start(); 
      System.out.println("Thread " + i + " gestartet"); 
     } // TODO Auto-generated constructor stub 

    } 
    } 

} 

class Threads extends Thread { 

    public Threads(int[][] a, int[][] b) { 
     run(a, b); 
    } 

    /* 
    * public Threadverteiler(Thread[] c, int[][] a,int[][]b) { //start(); 
    * run(a, b); //Arrays.spliterator(a); 
    * //System.out.println(Arrays.spliterator(a)); 
    * 
    * } 
    */ 

    public void run(int[][] a, int[][] b) { 
     // synchronized (this) { 

     // boolean arrayleer = false; 

     // int[][]cc= new int[5][5]; 

     // public int[][] rechnen(int[][] a,int[][]b){ 

     // while(arrayleer==true){ 
     int[][] aa = new int[5][5]; 
     int[][] bb = new int[5][5]; 
     int[][] cc = new int[5][5]; 

     aa = a; 
     bb = b; 

     for (int i = 0; i < aa.length; i++) 

     { 

      for (int j = 0; j < bb.length; j++) 

      { 

       for (int k = 0; k < cc.length; k++) 

       { 

        cc[i][j] = cc[i][j] + aa[i][k] * bb[k][j]; 
        // cc[i][j] = cc[i][j] + a[i][k] * b[k][j]; 

        /* 
        * if(cc[i][j]==0){ i++; j++; k++; continue; } else { 
        * System.out.println("Andere thread"); break; 
        * //arrayleer=false; } 
        */ 

       } 

      } 

     } 

     /* 
     * try { PrintWriter print = new PrintWriter(new File()); 
     * 
     * } catch (Exception e) { // TODO: handle exception } return cc; 
     * 
     * 
     * } } 
     */ 

     // c=cc; 
     // System.out.println("active Threads " + activeCount()); 

     System.out.println(Arrays.deepToString(cc)); 
     System.out.println("active Threads " + activeCount()); 

    } 

} 

// } 

public class Uebung2 { 

    public static void main(String[] args) { 

     int[][] a = { { 1, -2, 3, 4, -1 }, { -2, 3, 0, 1, 2 }, { 4, -1, 2, 1, -2 }, { -2, 1, 3, -1, 3 }, 
       { 0, 2, -1, 2, 4 } }; 
     int[][] b = { { 2, -4, -1, 1, -2 }, { -1, 1, -2, 2, 1 }, { 5, 0, 3, -2, -4 }, { 1, -2, 1, 0, 2 }, 
       { 2, 3, -3, 0, 0 } }; 

     // int[][] c= new int[5][5]; 

     // System.out.println(Arrays.deepToString(a)); 
     // System.out.println(Arrays.deepToString(b)); 

     // public static void threadauswahl(int x){ 

     // int i = 0; 

     System.out.println("Bitte Anzahl Threads eingeben"); 

     Scanner sc = new Scanner(System.in); 
     int eingabe = sc.nextInt(); 
     sc.close(); 

     Thread[] threads = new Thread[eingabe]; 

     // while (threads[i]==null) { 

     for (int i = 0; i < threads.length; i++) { 
      threads[i] = new Thread(new Threads(a, b)); 

      // threads[i].start(); // !!!!!!!!!!!!!!!!! ändern!! 
      // i++; 
     } 

     Threadverteiler s = new Threadverteiler(threads); 

    } 

} 

// System.out.println(Arrays.deepToString(a)); 
// System.out.println(Arrays.deepToString(b)); 
// System.out.println(Arrays.deepToString(c)); 
+0

'' Threads''のコンストラクタで '' run''メソッドを呼び出しています。 '' Threads''インスタンスだけを作成するのではなく、すでにあなたの作業を行い、_afterwards_複数のスレッドで実行しようとします。私はあなたが望むものではないと思う... – f1sh

+0

あなたがこれを書いた方法は、すべてのスレッドが同じ仕事を繰り返す。この問題の難しい部分は、ワークロードを独立して処理できる別個の部分に分割することです。問題の独立した部分を実行する方法があれば、それを並行して実行するのは簡単です。 – erickson

答えて

0

私が正しくあなたの質問を理解していれば、私が正しく理解していた場合は、次には、複数のスレッドに

public class Main { 

    public static void main(final String[] args) { 

     final int[][] a = { { 1, -2, 3, 4, -1 }, { -2, 3, 0, 1, 2 }, { 4, -1, 2, 1, -2 }, { -2, 1, 3, -1, 3 }, { 0, 2, -1, 2, 4 } }; 
     final int[][] b = { { 2, -4, -1, 1, -2 }, { -1, 1, -2, 2, 1 }, { 5, 0, 3, -2, -4 }, { 1, -2, 1, 0, 2 }, { 2, 3, -3, 0, 0 } }; 

     System.out.println("Bitte Anzahl Threads eingeben"); 

     final Scanner sc = new Scanner(System.in); 
     final int eingabe = sc.nextInt(); 
     sc.close(); 

     final Thread[] threads = new Thread[eingabe]; 

     for (int i = 0; i < threads.length; i++) { 
      threads[i] = new Thread(new Threads(a, b)); 
     } 

     final Threadverteiler s = new Threadverteiler(threads); 

    } 

} 

class Threadverteiler extends Thread { 

    public Threadverteiler(final Thread[] threads) { 
     synchronisiert(threads); 
    } 

    public void synchronisiert(final Thread[] t) { 

     final Thread[] threads = t; 
     synchronized (threads) { 
      for (int i = 0; i < threads.length; i++) { 

       threads[i].start(); 
       System.out.println("Thread " + i + " gestartet"); 
      } 

      for (int i = 0; i < threads.length; i++) { 
       try { 
        threads[i].join(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

} 

class Threads extends Thread { 

    private final int[][] a; 
    private final int[][] b; 

    public Threads(final int[][] a, final int[][] b) { 
     this.a = a; 
     this.b = b; 

    } 

    @Override 
    public void run() { 
     int[][] aa = new int[5][5]; 
     int[][] bb = new int[5][5]; 
     final int[][] cc = new int[5][5]; 

     aa = a; 
     bb = b; 

     for (int i = 0; i < aa.length; i++) { 
      for (int j = 0; j < bb.length; j++) { 
       for (int k = 0; k < cc.length; k++) { 
        cc[i][j] = cc[i][j] + aa[i][k] * bb[k][j]; 
       } 

      } 

     } 

     System.out.println(Arrays.deepToString(cc)); 
     System.out.println("active Threads " + activeCount()); 

    } 

} 
0

を開始する必要があり、このデザインは、すでにExecutorServiceFutureを経由して、APIに実装されています。これらは、マスター(ExecutorService)がタスクのリストを制御することを可能にします。各タスクのリストは、マトリックスのセグメントを含み、Futureは完了時にレポートします。あなたは未来のタスクごとに行列を分解しなければならないでしょうが、簡単なはずです。

+0

hmmは私が探していたようですが、どうすれば行列を分割できますか? 私はそれがSpliterator(名前のため)だと思っていましたが、プリミティブなデータ型にしか使えないようです。 – eraser51

+0

はい、Spliterator(「分割イテレータ」)はそうです。それを分割するためのアルゴリズムは、おおよその行列の大きさと、許容可能なパフォーマンスとメモリ使用量を維持しながら、特定のアプリケーションで考えられるワーカースレッドの数に大体基づいています。おそらく、スレッドの最大数は、非常に大きなコレクションでtrySplit()を何度呼び出すかのドライバになるでしょう。その番号は、あなたのアプリケーションのためだけにあなたが決定することができます。 – MolonLabe