2015-08-02 17 views
22

Ho scritto codice utilizzando java 8 stream e flussi paralleli per la stessa funzionalità con un raccoglitore personalizzato per eseguire una funzione di aggregazione. Quando vedo l'utilizzo della CPU usando htop, mostra tutti i core della CPU usati sia per la versione "stream" che per quella per i "flussi paralleli". Quindi, sembra quando viene utilizzato list.stream(), ma utilizza anche tutte le CPU. Qui, qual è la differenza esatta tra parallelStream() e stream() in termini di utilizzo di multi-core.Differenza tra flussi java 8 e flussi paralleli

+5

Gli stream non paralleli utilizzano solo un thread per elaborare la propria pipeline. Questo è un fatto difficile. A meno che non si esegua un multithreading esplicito con l'elaborazione del flusso, ogni operazione del terminale verrà eseguita su un singolo core alla volta. Se si fa riferimento al fatto che htop mostra l'utilizzo _some_ di tutti i core, ciò potrebbe essere dovuto allo stesso thread che migrava da core a core (non essendo pinnato su un singolo core). –

+2

Sarebbe meglio se fornissi il codice del tuo programma in modo che possiamo riprodurre il tuo effetto. Come diceva Marko, 'list.stream()' funziona in sequenza nello stesso thread in cui è stata emessa l'operazione del terminale, questo è fatto al 100%. Tuttavia non possiamo spiegare perché hai osservato l'utilizzo della CPU, perché non vediamo il tuo codice. –

+0

Si prega di trovare il codice qui - https://github.com/yogirjoshi/monitortools/blob/master/src/main/java/rithm/driver/Hypothesis2.java –

risposta

30

Si consideri il seguente programma:

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

Si noterà che questo programma sarà in uscita i numeri da 0 a 999 in sequenza, nell'ordine in cui sono nella lista. Se cambiamo stream() in parallelStream() questo non è più il caso (almeno sul mio computer): tutti i numeri sono scritti, ma in un ordine diverso. Quindi, apparentemente, parallelStream() utilizza in effetti più thread.

Il htop è spiegato dal fatto che anche le applicazioni a thread singolo sono suddivise su più core dalla maggior parte dei sistemi operativi moderni (parti dello stesso thread possono essere eseguite su più core, ma ovviamente non contemporaneamente). Quindi, se vedi che un processo utilizza più di un core, questo non significa necessariamente che il programma usi più thread.

Anche le prestazioni potrebbero non migliorare quando si utilizzano più thread. Il costo della sincronizzazione potrebbe non aumentare i vantaggi dell'utilizzo di più thread. Per scenari di test semplici questo è spesso il caso. Ad esempio, nell'esempio sopra, System.out è sincronizzato. Quindi, in modo efficace, solo il numero può essere scritto allo stesso tempo, sebbene vengano utilizzati più thread.