O que é Callable e Future em Java?
O Java oferece várias formas de gerenciar concorrência e threads. Quando precisamos executar tarefas assíncronas e obter um retorno da execução, utilizamos Callable e Future.
1. Diferença entre Runnable
e Callable
Característica | Runnable | Callable |
---|---|---|
Retorno | Não retorna resultado (void ) |
Retorna um valor genérico T |
Exceções | Não permite lançar exceções verificadas | Permite lançar Exception |
2. Criando uma Tarefa com Callable
Diferente de Runnable
, o Callable<T>
permite que uma thread retorne um valor:
import java.util.concurrent.Callable;
public class MinhaTarefa implements Callable<Integer> {
@Override
public Integer call() throws Exception {
Thread.sleep(1000);
return 42;
}
}
Explicação:
Callable<Integer>
indica que a tarefa retornará umInteger
.- O método
call()
executa o código e retorna um resultado.
3. Executando Callable
com ExecutorService
e Future
Para executar um Callable
, utilizamos um ExecutorService e capturamos o resultado com um Future:
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> resultado = executor.submit(new MinhaTarefa());
System.out.println("Resultado: " + resultado.get());
executor.shutdown();
}
}
Explicação:
submit(new MinhaTarefa())
envia a tarefa para execução.Future<Integer>
representa um valor que será computado no futuro.get()
bloqueia a execução até que o resultado esteja pronto.
4. Usando Future
sem Bloquear a Execução
Se quisermos verificar se a tarefa foi concluída sem bloquear a thread principal, usamos isDone()
:
while (!resultado.isDone()) {
System.out.println("Aguardando resultado...");
Thread.sleep(500);
}
System.out.println("Resultado final: " + resultado.get());
5. Cancelando uma Tarefa com Future
Podemos cancelar a execução de uma tarefa usando cancel(true)
, interrompendo a thread:
resultado.cancel(true);
if (resultado.isCancelled()) {
System.out.println("Tarefa cancelada.");
}
Conclusão
O uso de Callable e Future permite executar tarefas em paralelo e capturar seus resultados sem bloquear a aplicação. Esse recurso é essencial para aplicações de alto desempenho, como processamento de grandes volumes de dados e chamadas a APIs externas.
Por que Callable e Future são fundamentais para programação assíncrona?
Em sistemas modernos, muitas operações precisam ser realizadas de forma assíncrona. Um exemplo comum é o processamento de transações bancárias ou a comunicação com serviços externos. O uso de Callable e Future permite executar essas tarefas sem bloquear a aplicação principal, garantindo maior eficiência e escalabilidade.
Algumas aplicações:
- Execução de cálculos complexos em segundo plano
- Processamento assíncrono de dados em aplicações web
- Carregamento de informações sem bloquear a interface do usuário
- Execução de múltiplas requisições a APIs de forma concorrente
Dicas para quem está começando
- Use
Callable
quando precisar retornar um resultado de uma thread - Evite chamar
get()
diretamente para não bloquear a execução principal - Utilize
isDone()
para verificar o status da execução antes de acessar o resultado - Prefira
ExecutorService
para gerenciar chamadas concorrentes
Contribuições de Rodrigo Farias