2016-03-19 5 views
0

Um sich mit der parallelen Programmierung vertraut zu machen, wollte ich ein einfaches Java-Parallelprogramm erstellen, das die Summe aller Elemente eines Arrays unter Verwendung von 4 Threads berechnet. HierEinfaches Java-Parallelprogramm

ist die SumClass, die Thread-Klasse erweitert:

public class SumThread extends Thread { 
int lo; 
int ho; 
int Arr[]; 
int ans=0; 

//constructor 
SumThread(int Arr[], int lo, int ho){ 
    this.Arr = Arr; 
    this.lo = lo; 
    this.ho = ho; 
} 

public void run(){ 
    for (int i=lo; i<ho; i++){ 
     ans += Arr[i]; 
    } 
    } 
} 

Und hier haben wir die Hauptklasse:

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    int Arr[] = { 1, 3, 4, 5, 5, 6, 7, 2, 7, 5, 2, 4 }; 
    int ans = 0; 

    SumThread[] sum = new SumThread[4]; 

    for (int i = 0; i < 4; i++) { 
     sum[i] = new SumThread(Arr, (i * Arr.length)/4, Arr.length * ((i + 1)/4)); 
     sum[i].start(); 

    } 

    for (int i = 0; i < 4; i++) { 
     try { 
      sum[i].join(); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 

    } 
    for (int i = 0; i < 4; i++) { 
     ans += sum[i].ans; 
    } 

    System.out.println(ans); 

    } 

} 

Ich benutzte die join() Funktion für die Warte Threads, die vor dem Zugriff auf die ans-Werte abgeschlossen und gedruckt werden sollen. Der Punkt ist, dass ich 11 als Ergebnis bekomme, und das ist völlig falsch. Ich bemerkte, dass es nur die letzten 3 Werte (5,2,4) summiert. Es scheint, dass nur der vierte Thread gestartet wird.

Was mache ich falsch?

+0

'int ans = IntStream.of (Arr) .sum();' –

+0

Was Glaubst du, '(i + 1)/4' wird dir geben? Für "i" = 1 oder 2 ist es 0, und für 3 und 4 ist es 1. – bcsb1001

+0

Danke, es war wirklich ein dummer Fehler. Offensichtlich hast du Recht, ich kann Integer in diesem Teil nicht verwenden! Vielen Dank! Es funktioniert jetzt! – DevX10

Antwort

0

Es gibt keine Threadsicherheit, wie Sie die Daten weitergeben. Sie könnten einen ExecutorService verwenden und zumindest der Rückgabewert, der über eine Future übergeben wird, wäre threadsicher, allerdings würde ich eine der eingebauten Streams-API verwenden und sie könnte diesen ganzen Code durch 2-3 Zeilen ersetzen.

int[] array = { 1, 3, 4, 5, 5, 6, 7, 2, 7, 5, 2, 4 }; 
int sum = IntStream.of(array).parallel().sum(); 
System.out.println(sum); 

oder

System.out.println(IntStream.of(1, 3, 4, 5, 5, 6, 7, 2, 7, 5, 2, 4).parallel().sum()); 
+0

Ich brauche das Programm eigentlich nicht, ich weiß, dass es viel bessere Möglichkeiten gibt, diese Art von Arbeit zu erledigen. Aber wie ich in der Post schrieb, versuche ich, mich mit der parallelen Programmierung vertraut zu machen und herauszufinden, was in meinem Programm falsch ist, damit ich es lösen kann. Ich hoffe du hast es verstanden. – DevX10

+0

@Ergo in diesem Fall müssen Sie sicherstellen, dass die Ergebnisse im Haupt-Thread gelesen werden. Ich schlage vor, Sie drucken sie oder verwenden Sie Ihren Debugger, um zu sehen, was die Werte sind. –

0

Dies sollte Ihnen 51.

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    int Arr[] = { 1, 3, 4, 5, 5, 6, 7, 2, 7, 5, 2, 4 }; 
    int ans = 0; 

    SumThread[] sum = new SumThread[4]; 

    for (int i = 0; i < 4; i++) { 
     sum[i] = new SumThread(Arr, (i * Arr.length)/4, (Arr.length * (i + 1))/ 4); 
     sum[i].start(); 
    } 

    for (int i = 0; i < 4; i++) { 
     try { 
      sum[i].join(); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
     } 
    } 
    for (int i = 0; i < 4; i++) { 
     ans += sum[i].ans; 
    } 

    System.out.println(ans); 
} 

}