O que é Callable e Future em Java?

Callable e Future permitem executar tarefas assíncronas em Java e capturar os resultados de execução de threads.

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á um Integer.
  • 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.

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

Compartilhe este tutorial: O que é Callable e Future em Java

Compartilhe este tutorial

Continue aprendendo:

Como usar Executors para gerenciar threads em Java

Executors em Java facilitam o gerenciamento de múltiplas threads, otimizando a concorrência e evitando problemas de desempenho.

Tutorial anterior

Como criar um pool de threads em Java

Um pool de threads em Java gerencia múltiplas tarefas concorrentes, otimizando o uso dos recursos do sistema.

Próximo tutorial