2016-12-08 3 views
0

Ich möchte Daten mit mehreren Threads verarbeiten, aber im Moment läuft nur der erste Thread, dann wird es vollständig gestoppt.Nur erste Thread eingeben, kann folgende Threads nicht eingeben

Ich versuche, die Namen der Threads auszudrucken, aber ich gebe nur den ersten Thread ein. Es stoppt nur, obwohl das Programm weiter läuft. Es geht um die synchpoint.await() stoppt dann.

public class Solver { 
    final int N; 
    final float[][] data; 
    final CyclicBarrier barrier; 

class Worker implements Runnable { 
    public int myRow; 
    String name; 
    public CyclicBarrier synchPoint; 

    Worker(CyclicBarrier barrier, int row, String name) { 
     myRow = row; 
     this.name = name; 
     this.synchPoint = barrier; 
     this.run(); 
    } 

    public void run() { 
      System.out.println("Name: " + name); 
      processRow(myRow); 
      mergeRows(); 

      try { 
       System.out.print("In SynchPoint"); 
       synchPoint.await(); 
      } catch (InterruptedException ex) { 
       return; 
      } catch (BrokenBarrierException ex) { 
       return; 
      } 
    } 
} 

public void processRow(int numRow){ 
    System.out.println("In Process Row"); 
} 

public void mergeRows(){ 
    System.out.println("In merge Row"); 
} 

public Solver(float[][] matrix) { 
    data = matrix; 
    N = matrix.length; 
    System.out.println("N: " + N); 
    Runnable barrierAction = 
      new Runnable() { public void run() { mergeRows(); }}; 
    barrier = new CyclicBarrier(N, barrierAction); 

    List<Thread> threads = new ArrayList<Thread>(N); 
    for (int i = 0; i < N; i++) { 
     String myName = "Worker-" + i; 
     Thread thread = new Thread(new Worker(barrier, i, myName)); 
     threads.add(thread); 
     thread.start(); 
     System.out.println("In loop, i is: " + i); 
    } 

    // wait until done 
    for (Thread thread : threads) 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void doWork(){ 
     float[][] matrix2 = new float[6][2000]; 
     Solver solve = new Solver(matrix2); 
    } 

    public static void main(String[] args) { 
     Solver.doWork(); 
    } 
} 

Output:

N: 5
Name: Worker-0
In Process Row
Row ist: 0
Datenlänge: 5
In merge Row
In Zusammenführungszeile
In SynchPoint

+1

Ich nehme an, dies basiert auf der Probe aus dem [Javadoc] (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html). – shmosel

+1

Was ist Ihre volle Ausgabe? – shmosel

+0

Ja, es basiert auf der Probe. –

Antwort

5

Sie haben eine unangenehme Angewohnheit, Ihre Konstruktoren dazu zu bringen, anders als eine Instanz zu initialisieren. Es ist letztlich nicht schädlich, dass der Konstruktor Solver dies tut, aber die Tatsache, dass Solver.Worker die run() Methode der Instanz aufruft, ist die Quelle Ihres Problems.

Sie führen den Worker-Konstruktor im Hauptthread der Anwendung aus. Dieser Konstruktor ruft run() auf, wodurch der Thread ausgesetzt wird, wenn er synchPoint.await() erreicht. Der Thread würde fortgesetzt, wenn genügend andere Threads diesen Punkt erreichen, aber keiner wird jemals, weil der eine Thread, der getan hat, derjenige ist, der die anderen erstellt und gestartet hätte, und er kann nicht fortfahren.

Entfernen Sie die this.run() von Worker Konstruktor und Sie sollten viel weiter bekommen.

+0

Die unangenehme Angewohnheit ist wahrscheinlich vom [Javadoc-Beispiel] inspiriert (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html). – shmosel

+0

Das kann sehr gut sein, @shmosel, aber das macht es nicht weniger unangenehm. Ich hoffe, dass das OP aus meiner etwas rohen Charakterisierung eine starke Mahnung ist, das nicht zu tun. Wenn er auch denkt, dass ich ein Idiot bin - nun, ich kann damit leben. Jerkophobe sollten nicht das Internet besuchen. –