Ao desenvolver um aplicativo multi-threaded, geralmente devemos lidar com a organização do trabalho dos threads. Quanto maior for nosso aplicativo e quanto mais threads precisarmos para tarefas multithread, maisExecutávelobjetos que criamos.
Deve-se notar aqui que criar um thread em Java é uma operação bastante cara. Se criarmos uma nova instância do thread a cada vez para realizar uma operação, teremos grandes problemas com o desempenho e, como resultado, com a integridade do aplicativo.
Um pool de threads e ThreadPoolExecutor vêm em nosso auxílio aqui.
Um pool de threads é um conjunto de threads pré-inicializados. Seu tamanho pode ser fixo ou variável.

Se houver mais tarefas do que threads, as tarefas aguardarão em uma fila de tarefas. O enésimo encadeamento no pool pega uma tarefa da fila e, depois de concluído, o encadeamento pega uma nova tarefa da fila. Depois que todas as tarefas na fila são executadas, os threads permanecem ativos e aguardam novas tarefas. Quando novas tarefas aparecem, os threads começam a executá-las também.
ThreadPoolExecutor
A partir do Java 5, o framework Executor ganhou uma solução multithreading. Em geral, ele possui muitos componentes e seu objetivo é nos ajudar a gerenciar com eficiência filas e pools de threads.
As interfaces principais são Executor e ExecutorService .
Executor é uma interface com um único método void execute(Runnable runnable).
Ao passar uma tarefa para uma implementação desse método, saiba que futuramente ela será executada de forma assíncrona.
ExecutorService — Uma interface que estende a interface Executor , adicionando recursos para executar tarefas. Ele também possui métodos para interromper uma tarefa em execução e encerrar o pool de encadeamentos.
ThreadPoolExecutor implementa as interfaces Executor e ExecutorService e separa a criação da tarefa da execução da tarefa. Precisamos implementar objetos Runnable e enviá-los para um executor. O ThreadPoolExecutor é então responsável por executar as tarefas, criar e trabalhar com threads.

Depois que uma tarefa é enviada para execução, um thread existente no pool é usado. Isso melhora o desempenho. Ele resolve o problema de desperdício de recursos na criação e inicialização de um novo encadeamento e, novamente, na coleta de lixo quando terminamos o encadeamento.
ThreadPoolExecutor tem 4 construtores:
ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
O construtor ThreadPoolExecutor tem os seguintes parâmetros:
corePoolSize | Este parâmetro indica quantas threads estarão prontas (iniciadas) quando o serviço executor for iniciado. |
MaximumPoolSize | O número máximo de encadeamentos que um serviço executor pode criar. |
KeepAliveTime | O tempo que um thread liberado continuará a viver antes de ser destruído se o número de threads for maior quecorePoolSize. As unidades de tempo são especificadas no próximo parâmetro. |
unidade | Unidades de tempo (horas, minutos, segundos, milissegundos, etc.). |
fila de trabalho | Implementação de uma fila de tarefas. |
manipulador | Manipulador para tarefas que não podem ser concluídas. |
threadFactory | Um objeto que cria novos threads sob demanda. O uso de fábricas de encadeamentos torna as chamadas para um novo hardware de encadeamento independente, permitindo que os aplicativos usem subclasses de encadeamentos especiais, prioridades e assim por diante. |
Criando um ThreadPoolExecutor
A classe de utilitário Executors pode simplificar a criação de um ThreadPoolExecutor . Os métodos desta classe utilitária nos ajudam a preparar umThreadPoolExecutorobjeto.
newFixedThreadPool — Cria um pool de threads que reutiliza um número fixo de threads para executar qualquer número de tarefas. |
|
newWorkStealingPool — Cria um conjunto de encadeamentos em que o número de encadeamentos é igual ao número de núcleos de processador disponíveis para a JVM. O nível de simultaneidade padrão é um. Isso significa que tantos encadeamentos serão criados no pool quantos forem os núcleos de CPU disponíveis para a JVM. Se o nível de simultaneidade for 4, o valor passado será usado em vez do número de núcleos. |
|
newSingleThreadExecutor — Cria um pool com um único thread para executar todas as tarefas. |
|
newCachedThreadPool — Cria um pool de encadeamentos que cria novos encadeamentos conforme necessário, mas reutiliza os encadeamentos criados anteriormente quando eles estão disponíveis. |
|
newScheduledThreadPool — Cria um pool de encadeamentos que pode agendar comandos para execução após um determinado atraso ou periodicamente. |
|
Vamos considerar cada tipo de piscina nas próximas lições.
GO TO FULL VERSION