2015-08-02 7 views
22

Ich schrieb Code mit Java 8 Streams und parallelen Streams für die gleiche Funktionalität mit einem benutzerdefinierten Kollektor, um eine Aggregationsfunktion durchzuführen. Wenn ich die CPU-Auslastung mit htop sehe, werden alle CPU-Kerne angezeigt, die für die Versionen "Streams" und "Parallel Streams" verwendet werden. So scheint es, wenn list.stream() verwendet wird, verwendet es auch alle CPUs. Was ist der genaue Unterschied zwischen parallelStream() und Strom() in Bezug auf Verwendung von Multi-Core.Unterschied zwischen Java 8 Streams und parallelen Streams

+5

Nichtparallele Streams verwenden nur einen Thread zur Verarbeitung ihrer Pipeline. Das ist eine harte Tatsache. Wenn Sie nicht explizites Multithreading mit der Stream-Verarbeitung durchführen, wird jede Terminaloperation auf einem einzelnen Kern gleichzeitig ausgeführt. Wenn Sie sich darauf beziehen, dass "htop" eine gewisse Auslastung aller Kerne anzeigt, liegt das vielleicht daran, dass der gleiche Thread von Core zu Core migriert (nicht an einen einzelnen Core angeheftet). –

+2

Es wäre besser, wenn Sie den Code Ihres Programms angeben, damit wir Ihren Effekt reproduzieren können. Wie Marko sagte, funktioniert 'list.stream()' sequenziell in demselben Thread, in dem der Terminal-Vorgang ausgeführt wurde, das ist 100% Fakt. Wir können jedoch nicht erklären, warum Sie die gesamte CPU-Auslastung beobachtet haben, da wir Ihren Code nicht sehen. –

+0

Den Code finden Sie hier - https://github.com/yogirjoshi/monitortools/blob/master/src/main/java/rithm/driver/Hypothesis2.java –

Antwort

30

Betrachten Sie das folgende Programm:

import java.util.ArrayList; 
import java.util.List; 

public class Foo { 
    public static void main(String... args) { 
     List<Integer> list = new ArrayList<>(); 
     for (int i = 0; i < 1000; i++) { 
      list.add(i); 
     } 
     list.stream().forEach(System.out::println); 
    } 
} 

Sie werden feststellen, dass dieses Programm gibt die Zahlen von 0 bis 999 nacheinander in der Reihenfolge, in der sie in der Liste enthalten sind. Wenn wir stream() zu parallelStream() ändern, ist das nicht mehr der Fall (zumindest auf meinem Computer): alle Nummern werden geschrieben, aber in einer anderen Reihenfolge. Offensichtlich verwendet parallelStream() tatsächlich mehrere Threads.

Die htop wird durch die Tatsache erklärt, dass sogar single-threaded-Anwendungen über mehrere Kerne von den meisten modernen Betriebssystemen geteilt werden (Teile des gleichen Threads können auf mehreren Kernen laufen, aber natürlich nicht zur gleichen Zeit). Wenn Sie also sehen, dass ein Prozess mehr als einen Kern verwendet, bedeutet dies nicht unbedingt, dass das Programm mehrere Threads verwendet.

Auch die Leistung kann nicht verbessert werden, wenn mehrere Threads verwendet werden. Die Kosten der Synchronisierung können die Vorteile der Verwendung mehrerer Threads nicht erhöhen. Für einfache Testszenarien ist dies oft der Fall. Zum Beispiel ist System.out im obigen Beispiel synchronisiert. So kann effektiv nur die Nummer gleichzeitig geschrieben werden, obwohl mehrere Threads verwendet werden.