✅ Use Parallel Streams

Incluindo:
📌 reduction | 📌 decomposition | 📌 merging processes | 📌 pipelines | 📌 performance


🧠 RESUMO

parallelStream() é uma forma de paralelizar o processamento de dados em streams usando o Fork/Join framework por baixo dos panos.

Streams paralelos dividem a fonte de dados e processam em múltiplas threads, automaticamente.


🔍 COMO FUNCIONA?

list.parallelStream()
.filter(...)
.map(...)
.collect(...);

parallelStream() vs stream()

MétodoExecução
stream()Sequencial
parallelStream()Paralela

Você também pode fazer:

list.stream().parallel() 
// transforma em paralelo no meio da pipeline

🔧 REDUCTION

Redução é o processo de reduzir elementos da stream a um único resultado, como sum, average, reduce.

⚠️ Cuidados com operações não associativas:

list.parallelStream().reduce((a, b) -> a - b) 
// pode gerar resultado incorreto!

✅ Preferir operações associativas e sem efeitos colaterais:

list.parallelStream().reduce(0, Integer::sum)

📦 DECOMPOSITION E MERGE

  • O Java divide os dados em partes menores (fork).
  • Processa em paralelo com ForkJoin.
  • Combina (join) os resultados no final (merge).

Exemplo:

List<Integer> nums = Arrays.asList(1,2,3,4,5,6);
int total = nums.parallelStream()
.map(n -> n * 2)
.reduce(0, Integer::sum);

🔁 PIPELINES

Stream pipelines são compostas de:

  1. Fonte (ex: List)
  2. Operações intermediárias (ex: filter, map)
  3. Operação terminal (ex: collect, reduce)

Em paralelo, tudo acontece em múltiplas threads de forma transparente.


🚀 PERFORMANCE

✅ Vantagens:

  • Aproveita múltiplos núcleos (CPU).
  • Fácil paralelização sem usar Thread ou ForkJoinPool manualmente.

⚠️ Desvantagens:

  • Pode ser mais lento para coleções pequenas.
  • Cuidado com acesso a recursos compartilhados (como arquivos, listas não thread-safe).
  • Evite usar streams paralelos em ambientes altamente concorrentes com efeitos colaterais.

🛠️ EXEMPLO COMPLETO

import java.util.*;
import java.util.stream.*;

public class ParallelStreamExample {
  public static void main(String[] args) {
    List<Integer> numbers = IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toList());

    int result = numbers.parallelStream()
                        .map(n -> n * 2)
                        .filter(n -> n % 3 == 0)
                        .reduce(0, Integer::sum);

    System.out.println("Resultado final: " + result);
  }
}

⚠️ ERROS COMUNS NA PROVA

  1. Usar operações com efeitos colaterais, como modificar uma variável externa.
  2. Assumir que a ordem de execução é garantida — não é em paralelo!
  3. Esperar performance melhor em qualquer caso — streams pequenos ou com muita sincronização podem ser mais lentos.
  4. Utilizar coleções não thread-safe como destino de collect() sem Collectors.toConcurrentMap() ou toConcurrentList().

🧠 DICAS PARA A PROVA

  • Use parallelStream() quando:
    • Os dados são grandes.
    • As operações são independentes entre si.
    • As operações são associativas e sem efeitos colaterais.
  • Use forEachOrdered() se quiser preservar a ordem mesmo em paralelo.
  • collect() pode ser usado com Collector personalizado ou com Collectors prontos (como toList(), toMap(), joining()).

📝 10 QUESTÕES DE PRÁTICA

1. Qual operação é segura em um parallelStream()?

A) Subtrair valores em ordem
B) Concatenar strings em variável externa
C) Somar valores com reduce(0, Integer::sum)
D) Acessar uma lista sem sincronização


2. O que parallelStream() usa internamente?

A) ThreadPoolExecutor
B) ForkJoinPool ✅
C) ExecutorService
D) Threads manuais


3. Qual operação garante ordem mesmo com parallelStream()?

A) forEach
B) forEachOrdered ✅
C) collect
D) sorted


4. Qual operação é terminal?

A) filter
B) map
C) collect ✅
D) peek


5. O que pode causar problemas de performance em parallelStream()?

A) Tarefas puramente funcionais
B) Tarefas pequenas com overhead alto ✅
C) Redução com soma
D) Uso de reduce associativo


6. O que reduce(0, Integer::sum) faz?

A) Soma os elementos ✅
B) Multiplica os elementos
C) Retorna uma média
D) Subtrai da esquerda para direita


7. Quando usar parallelStream() pode ser problemático?

A) Operações com efeitos colaterais ✅
B) Dados imutáveis
C) Quando todos os dados são pares
D) Quando se quer desempenho


8. stream().parallel() transforma a stream em quê?

A) Stream sequencial
B) Stream paralela ✅
C) Array
D) Lista modificável


9. Em qual cenário parallelStream() provavelmente terá ganho de performance?

A) Lista com 5 elementos
B) Operações lentas em lista grande ✅
C) Leitura de arquivos
D) Prints na tela


10. Qual alternativa é falsa?

A) parallelStream usa múltiplos núcleos
B) Ordem de execução é garantida ❌
C) forEachOrdered garante ordem ✅
D) reduce deve ser associativo