Executors e Futures¶
Um Executor desacopla o envio de tarefas da política de execução. Um
ExecutorService acrescenta gerenciamento do ciclo de vida e dos resultados.
Escolha e assuma a responsabilidade pela política¶
- pools fixos limitam as threads de plataforma ativas segundo políticas conhecidas para CPU ou bloqueio;
- pools com roubo de trabalho aceitam computações decompostas recursivamente;
- executores com uma thread virtual por tarefa aceitam um estilo bloqueante de alta concorrência;
- executores agendados tratam trabalho atrasado e periódico.
Todo executor criado precisa de um responsável e de uma política de encerramento. A capacidade da fila, o comportamento de rejeição, a duração das tarefas e a capacidade dos serviços dependentes fazem parte do projeto do sistema. Consulte pools e recursos limitados para saturação, empréstimo de conexões, medição de capacidade e riscos de pools aninhados.
Future e CompletableFuture¶
Um Future representa um resultado futuro e permite espera e cancelamento.
CompletableFuture constrói grafos assíncronos de dependências.
CompletableFuture<Integer> total = CompletableFuture
.supplyAsync(() -> loadLeft(), executor)
.thenCombine(
CompletableFuture.supplyAsync(() -> loadRight(), executor),
Integer::sum)
.orTimeout(2, TimeUnit.SECONDS);
Escolha deliberadamente entre continuações síncronas (thenApply) e assíncronas
(thenApplyAsync) e forneça um executor quando a política de execução importar.
As exceções fazem parte do grafo; defina onde serão traduzidas ou tratadas.
Backpressure¶
Enviar trabalho mais rapidamente do que ele termina cria uma fila implícita ou explícita. Uma fila ilimitada troca a rejeição imediata por riscos ilimitados de latência e memória. Limite a concorrência no recurso que não pode escalar e propague deadlines ou o cancelamento, em vez de permitir o acúmulo de trabalho obsoleto. Uma fila não fornece backpressure a menos que atingir seu limite restrinja o produtor segundo uma política explícita; o guia de controles de resiliência desenvolve essa distinção.