logo

Java ExecutorService

O Java ExecutorService é a interface que nos permite executar tarefas em threads de forma assíncrona. A interface Java ExecutorService está presente no pacote java.util.concurrent. O ExecutorService ajuda a manter um pool de threads e atribui tarefas a eles. Ele também fornece a facilidade de enfileirar tarefas até que haja um thread livre disponível se o número de tarefas for maior que o número de threads disponíveis.

Java ExecutorService

Métodos de Java ExecutorService

Método Descrição
boolean waitTermination(tempo limite longo, unidade TimeUnit) Este método bloqueia a tarefa para entrar no ExecutorService até que todas as tarefas sejam concluídas após a solicitação de desligamento, ou o tempo limite determinado ocorra, ou o thread atual seja interrompido, o que acontecer primeiro.
ListainvocarAll(Coleçãotarefas) Este método executa a lista de tarefas fornecidas e retorna a lista de Futuros que contém os resultados de todas as tarefas quando concluídas.
ListainvocarAll(Coleçãotarefas, tempo limite longo, unidade TimeUnit) Este método executa a lista de tarefas fornecidas e retorna a lista de Futuros que contém os resultados de todas as tarefas quando concluídas ou quando o tempo limite expirar, o que ocorrer primeiro.
T invocaAny(Coleçãotarefas) Este método executa a lista de tarefas fornecidas e retorna o resultado de uma tarefa que é concluída sem gerar nenhuma exceção.
T invocaAny(Coleçãotarefas, tempo limite longo, unidade TimeUnit) Este método executa a lista de tarefas fornecidas e retorna o resultado de uma tarefa que é concluída sem lançar nenhuma exceção antes que o tempo limite termine.
booleano éShutdown() Este método retorna se o executor fornecido está desligado ou não.
booleano éTerminado() Este método retorna verdadeiro se todas as tarefas foram executadas após o desligamento.
desligamento vazio() Este método permite a conclusão de tarefas previamente enviadas ao ExecutorService e não permite a aceitação de nenhuma outra tarefa.
Lista shutdownNow() Este método interrompe todas as tarefas em execução ativa, interrompe a execução de tarefas enfileiradas e retorna a lista de tarefas enfileiradas.
Envio futuro (tarefa chamável) Este método envia uma tarefa que retorna valor para execução e retorna o Future, que representa o resultado pendente da tarefa.
Envio futuro (tarefa executável) Este método envia uma tarefa para execução e retorna um Future representando essa tarefa. Ele retorna nulo após a conclusão bem-sucedida.
Envio futuro (tarefa executável, resultado T) Este método envia uma tarefa para execução e retorna um Future representando essa tarefa.

Um programa simples de Java ExecutorService

 public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); executorService.shutdown(); } } 

Saída:

Java ExecutorService

Neste programa, estamos criando um ExecutorService com dez threads e atribuindo a ele uma implementação executável anônima que executa uma tarefa para imprimir 'ExecutorService' e após o término de sua tarefa, estamos desligando o serviço executor.

Como usar Java ExecutorService

Instanciando ExecutorService

Podemos usar Java ExecutorService para criar um único encadeamento, um conjunto de encadeamentos ou um conjunto agendado de encadeamentos. A classe Executors fornece métodos de fábrica para instanciar um ExecutorService da seguinte forma:

 ExecutorService executorService1 = Executors.newSingleThreadExecutor(); //Creates //a ExecutorService object having a single thread. ExecutorService executorService2 = Executors.newFixedThreadPool(10); // Creates a //ExecutorService object having a pool of 10 threads. ExecutorService executorService3 = Executors.newScheduledThreadPool(10); //Creates a scheduled thread pool executor with 10 threads. In scheduled thread //pool, we can schedule tasks of the threads. 

Atribuindo tarefas ao ExecutorServices

Para atribuir uma tarefa ao ExecutorService, podemos usar os seguintes métodos-

  • executar (tarefa executável)
  • submit(tarefa executável) / submit(tarefa chamável)
  • invocarAny(Coleçãotarefas)
  • invocarAll(Coleçãotarefas)

Exemplo de atribuição de uma tarefa ao ExecutorService usando o método execute()

O método execute() do Java ExecutorService recebe um objeto executável e executa sua tarefa de forma assíncrona. Após fazer a chamada ao método execute, chamamos o método shutdown, que bloqueia qualquer outra tarefa para enfileirar-se no executorService.

 public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); executorService.shutdown(); } } 

Saída:

 ExecutorService 

Exemplo de atribuição de uma tarefa ao ExecutorService usando submit()

O método submit() recebe um objeto executável e retorna um objeto Future. Este objeto é posteriormente usado para verificar o status do Runnable, independentemente de ele ter concluído a execução ou não.

 public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.submit(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); } } 

Exemplo de atribuição de uma tarefa ao ExecutorService usando o método InvokeAny()

O método InvokeAny() pega uma coleção de objetos Callablle ou objetos de classes que implementam Callable. Este método retorna o objeto futuro do objeto que pode ser chamado que é executado primeiro com sucesso.

 public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<callable> callables = new HashSet<callable>(); callables.add(new Callable() { public String call() throws Exception { return &apos;Task 1&apos;; } }); callables.add(new Callable() { public String call() throws Exception { return &apos;Task 2&apos;; } }); callables.add(new Callable() { public String call() throws Exception { return &apos;Task 3&apos;; } }); String result = executorService.invokeAny(callables); System.out.println(&apos;result = &apos; + result); executorService.shutdown(); } } </callable></callable>

Saída:

 result = Task 1 

O resultado armazena a Tarefa 1 quando o primeiro objeto que pode ser chamado é executado primeiro com êxito.

Exemplo de atribuição de uma tarefa ao ExecutorService usando o método InvokeAll()

O método invocaAll() recebe uma coleção de objetos que podem ser chamados com tarefas e retorna uma lista de objetos Future contendo o resultado de todas as tarefas.

 public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<callable> callables = new HashSet<callable>(); callables.add(new Callable() { public String call() throws Exception { return &apos;Task 1&apos;; } }); callables.add(new Callable() { public String call() throws Exception { return &apos;Task 2&apos;; } }); callables.add(new Callable() { public String call() throws Exception { return &apos;Task 3&apos;; } }); java.util.List<future> futures = executorService.invokeAll(callables); for(Future future : futures){ System.out.println(&apos;future.get = &apos; + future.get()); } executorService.shutdown(); } } </future></callable></callable>

Saída:

 future.get = Task 1 future.get = Task 3 future.get = Task 2 

Como desligar o ExecutorService

Assim que terminarmos nossas tarefas atribuídas ao ExecutorService, teremos que encerrá-lo porque o ExecutorService executa a tarefa em threads diferentes. Se não encerrarmos o ExecutorService, os threads continuarão em execução e a JVM não será encerrada.

O processo de desligamento pode ser feito pelos três métodos a seguir:

  • método shutdown()
  • método shutdownNow()
  • Método waitTermination()