Ciclo de Vida de Threads
Threads possuem cinco estados: criação, pronto, execução, bloqueado e encerrado. Na criação, o objeto thread é instanciado. No estado pronto, após start(), aguarda alocação de CPU. Execução ocorre quando a thread obtém recursos CPU. Bloqueio acontece quando libera CPU voluntariamente (wait, sleep, I/O), e encerramento ao finalizar run() ou por exceção.
Diferenças Entre sleep(), wait(), join() e yield()
sleep(): Pausa temporária sem liberar bloqueios. wait(): Libera recursos e bloqueios, exigindo notify()/notifyAll() para retorno. join(): Bloqueia a thread chamante até a finalização da thread alvo. yield(): Transfere voluntariamente controle para outras threads no estado pronto.
public class ExemploJoin {
public static void main(String[] args) throws InterruptedException {
Thread tarefa = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Processo secundário concluído");
});
tarefa.start();
tarefa.join();
System.out.println("Processo principal finalizado");
}
}
Segurança em Threads
Refere-se à garantia de comportamento correto durante acesso concorrente a dados compartilhados na memória heap. Requer sincronização para evitar condições de corrida e inconsistências.
Thread vs Runnable
Ambos executam tarefas concorrentes, mas Runnable favorece composição sobre herança. Thread cria instâncias independentes, enquanto Runnable permite compartilhamento de estado entre threads.
// Implementação Runnable
public class TarefaCompartilhada implements Runnable {
private int contador = 3;
public void run() {
while (contador > 0) {
System.out.println("Valor: " + contador--);
}
}
}
Threads Daemon
Executam em segundo plano para serviços auxiliares (ex: garbage collection). Terminam automaticamente quando todas as threads não-daemon finalizam.
ThreadLocal: Princípio e Uso
Armazena dados isolados por thread via mapa interno (ThreadLocalMap). Aplicações típicas incluem transações, conexões de BD e gerenciamento de sessão.
Vazamentos de Memória em ThreadLocal
Ocorrem quando entradas chave=null persistem no mapa após remoção do ThreadLocal. Prevenção: use remove() após operações ou declare ThreadLocal como static.
Concorrência, Paralelismo e Serial
Serial: Execução sequencial. Paralelismo: Execução simultânea em múltiplos núcleos. Concorrência: Intercalação de tarefas em único núcleo.
Propriedades da Concorrência
- Atomicidade: Operações indivisíveis (synchronized)
- Visibilidade: Alterações visíveis imediatamente (volatile)
- Ordenação: Prevenção de reordenação de instruções (volatile/synchronized)
Variáveis Volatile
Garante visibilidade imediata de alterações entre threads e previte reordenação de instruções. Não oferece atomicidade para operações compostas.
Fundamentos de ThreadPool
Melhora desempenho reutilizando threads. Parâmetros-chave:
- corePoolSize: Threads ativas permanentes
- maxPoolSize: Limite máximo de threads
- keepAliveTime: Tempo de vida para threads excedentes
- workQueue: Fila de tarefas pendentes
Fila de Bloqueio em ThreadPools
Armazena tarefas excedentes temporariamente. Prioriza filas sobre criação de novas threads para evitar custos de inicialização e gerenciamento excessivo.
Reutilização de Threads
Threads executam loops internos que consomem tarefas da fila. Evita criação/destruição contínua através de tarefas reutilizáveis.