pacote java.util.concurrent, com foco em CyclicBarrier e CopyOnWriteArrayList

🧠 RESUMO DO TÓPICO

O pacote java.util.concurrent fornece coleções e utilitários para facilitar a programação concorrente. Alguns dos mais relevantes para a prova incluem:

CopyOnWriteArrayList

  • Versão thread-safe de ArrayList.
  • Ideal quando há mais leituras do que escritas.
  • Ao modificar (add/remove/set), cria-se uma cópia da lista.
  • Muito usada em cenários de leitura frequente + escrita ocasional.

CyclicBarrier

  • Sincroniza um conjunto de threads que devem esperar umas pelas outras para atingir um ponto comum (barreira).
  • Muito útil em algoritmos paralelos que precisam “sincronizar” antes de prosseguir.

🔍 DETALHAMENTO + EXEMPLOS

🔹 CopyOnWriteArrayList

📌 Características

  • Não lança ConcurrentModificationException.
  • Operações de escrita são custosas, pois envolvem cópia da lista.
  • Métodos comuns: add(), remove(), get(), iterator() (iterador que não é afetado por alterações posteriores).

📌 Exemplo:

import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteExample {
  public static void main(String[] args) {
    CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
    list.add("Java");
    list.add("OCP");

    for (String item : list) {
      System.out.println(item);
      list.add("Nova"); // NÃO causa ConcurrentModificationException
    }

    System.out.println("Tamanho final: " + list.size()); 
// Pode imprimir 6, dependendo do loop
  }
}

🔹 CyclicBarrier

📌 Características

  • Criado com um número fixo de threads.
  • Cada thread chama await(), e todas ficam esperando até que todas tenham chamado.
  • Opcional: uma barreira de ação (Runnable que executa quando todas as threads chegam).

📌 Exemplo:

import java.util.concurrent.*;

public class CyclicBarrierExample {
  public static void main(String[] args) {
    Runnable barrierAction = () -> System.out.println("Todas as threads chegaram!");

    CyclicBarrier barrier = new CyclicBarrier(3, barrierAction);

    Runnable task = () -> {
      try {
        System.out.println(Thread.currentThread().getName() + " aguardando na barreira");
        barrier.await();
        System.out.println(Thread.currentThread().getName() + " passou da barreira");
      } catch (Exception e) {
        e.printStackTrace();
      }
    };

    for (int i = 0; i < 3; i++) {
      new Thread(task).start();
    }
  }
}

⚠️ ERROS COMUNS NA PROVA

  1. Confundir CopyOnWriteArrayList com Collections.synchronizedList():
    • O segundo ainda pode lançar ConcurrentModificationException com iteradores.
  2. Achar que CopyOnWriteArrayList é eficiente para escrita — não é!
  3. Achar que CyclicBarrier reinicia sozinha — sim, ela pode ser reutilizada, diferente de CountDownLatch.
  4. Esquecer que await() pode lançar InterruptedException e BrokenBarrierException.
  5. Achar que as listas thread-safe bloqueiam threadsCopyOnWriteArrayList não bloqueia leitura.

📘 DICAS PARA A PROVA

  • Leia atentamente os tipos de exceções que podem ser lançadas.
  • Se uma questão envolve concorrência, pense: “Quantas threads estão acessando/modificando?”.
  • Perguntas podem envolver desempenho: CopyOnWriteArrayList = boa para leitura, ruim para escrita.
  • Decore os métodos principais de cada classe (add(), remove(), await()…).
  • Entenda o comportamento de iteradores em listas concorrentes.

📝 10 QUESTÕES DE PRÁTICA

1. O que acontece se uma CopyOnWriteArrayList é modificada durante a iteração?

A) Lança ConcurrentModificationException
B) As mudanças aparecem na iteração
C) As mudanças são ignoradas na iteração atual ✅
D) O iterador trava a lista


2. Qual é a principal vantagem do CopyOnWriteArrayList?

A) Escrita eficiente
B) Leitura eficiente em ambiente concorrente ✅
C) Melhor performance que ArrayList
D) Permite paralelismo


3. O que faz barrier.await() em CyclicBarrier?

A) Inicia uma nova thread
B) Aguarda todas as threads chegarem à barreira ✅
C) Cancela a execução
D) Espera indefinidamente


4. CopyOnWriteArrayList pode lançar ConcurrentModificationException?

A) Sim
B) Não ✅
C) Apenas em gravações
D) Depende do número de threads


5. Qual exceção NÃO pode ser lançada por CyclicBarrier.await()?

A) InterruptedException
B) TimeoutException
C) ExecutionException ✅
D) BrokenBarrierException


6. CyclicBarrier pode ser reutilizada?

A) Sim ✅
B) Não
C) Apenas uma vez
D) Apenas com CountDownLatch


7. Em qual cenário usar CopyOnWriteArrayList?

A) Muitos writes, poucas reads
B) Muitos reads, poucos writes ✅
C) Muitas threads de escrita simultânea
D) Acesso exclusivo por uma thread


8. Quantas vezes o Runnable da CyclicBarrier é executado?

A) Nenhuma
B) Uma por thread
C) Uma por barreira completa ✅
D) Depende do número de chamadas


9. Qual é o comportamento padrão se uma das threads não chamar await()?

A) A barreira é quebrada
B) As outras continuam
C) As outras ficam esperando indefinidamente ✅
D) Lança IllegalStateException


10. Qual alternativa é thread-safe por padrão?

A) ArrayList
B) LinkedList
C) CopyOnWriteArrayList ✅
D) TreeSet