ThreadPoolExecutor Classe
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Um ExecutorService que executa cada tarefa enviada usando um dos vários threads em pool, normalmente configurados usando Executors métodos de fábrica.
[Android.Runtime.Register("java/util/concurrent/ThreadPoolExecutor", DoNotGenerateAcw=true)]
public class ThreadPoolExecutor : Java.Util.Concurrent.AbstractExecutorService
[<Android.Runtime.Register("java/util/concurrent/ThreadPoolExecutor", DoNotGenerateAcw=true)>]
type ThreadPoolExecutor = class
inherit AbstractExecutorService
- Herança
- Derivado
- Atributos
Comentários
Um ExecutorService que executa cada tarefa enviada usando um dos vários threads em pool, normalmente configurados usando Executors métodos de fábrica.
Os pools de threads resolvem dois problemas diferentes: eles geralmente fornecem um melhor desempenho ao executar um grande número de tarefas assíncronas, devido à redução da sobrecarga de invocação por tarefa e fornecem um meio delimitar e gerenciar os recursos, incluindo threads, consumidos ao executar uma coleção de tarefas. Cada ThreadPoolExecutor um também mantém algumas estatísticas básicas, como o número de tarefas concluídas.
Para ser útil em uma ampla variedade de contextos, essa classe fornece muitos parâmetros ajustáveis e ganchos de extensibilidade. No entanto, os programadores são instados a usar os métodos de fábrica mais convenientes ExecutorsExecutors#newCachedThreadPool (pool de threads não associados, com recuperação automática de thread), Executors#newFixedThreadPool (pool de threads de tamanho fixo) e Executors#newSingleThreadExecutor (thread de plano de fundo único), que pré-configuram para os cenários de uso mais comuns. Caso contrário, use o seguinte guia ao configurar e ajustar manualmente esta classe:
<dl>
<dt>Core e tamanhos máximos< do pool/dt>
<dd>A ThreadPoolExecutor ajustará automaticamente o tamanho do pool (consulte #getPoolSize) de acordo com os limites definidos por corePoolSize (consulte #getCorePoolSize) e maximumPoolSize (consulte #getMaximumPoolSize).
Quando uma nova tarefa é enviada no método #execute(Runnable), se menos de threads corePoolSize estiverem em execução, um novo thread será criado para lidar com a solicitação, mesmo que outros threads de trabalho estejam ociosos. Caso contrário, se menos de threads maximumPoolSize estiverem em execução, um novo thread será criado para lidar com a solicitação somente se a fila estiver cheia. Ao definir corePoolSize e maximumPoolSize o mesmo, você cria um pool de threads de tamanho fixo. Ao definir maximumPoolSize como um valor essencialmente não associado, como Integer.MAX_VALUE, você permite que o pool acomode um número arbitrário de tarefas simultâneas. Normalmente, os tamanhos de pool principal e máximo são definidos somente após a construção, mas também podem ser alterados dinamicamente usando #setCorePoolSize e #setMaximumPoolSize.
</dd>
<dt>Construção< sob demanda/dt>
<dd>Por padrão, até mesmo os threads principais são inicialmente criados e iniciados somente quando novas tarefas chegam, mas isso pode ser substituído dinamicamente usando o método #prestartCoreThread ou #prestartAllCoreThreads. Você provavelmente deseja executar threads se construir o pool com uma fila não vazia.
</dd>
<dt>Criando novos threads</dt>
<dd>Novos threads são criados usando um ThreadFactory. Se não for especificado de outra forma, um Executors#defaultThreadFactory é usado, que cria threads para que todos estejam no mesmo ThreadGroup e com a mesma NORM_PRIORITY prioridade e status não daemon. Ao fornecer um ThreadFactory diferente, você pode alterar o nome do thread, o grupo de threads, a prioridade, o status do daemon etc. Se não ThreadFactory for possível criar um thread quando solicitado retornando nulo, newThreado executor continuará, mas talvez não seja capaz de executar nenhuma tarefa. Os threads devem possuir o "modifyThread" RuntimePermission. Se threads de trabalho ou outros threads que usam o pool não tiverem essa permissão, o serviço poderá ser prejudicado: as alterações de configuração podem não entrar em vigor em tempo hábil e um pool de desligamento poderá permanecer em um estado no qual a terminação é possível, mas não concluída.</dd>
<dt>Keep-alive times</dt>
<dd>Se o pool atualmente tiver mais do que threads corePoolSize, os threads em excesso serão encerrados se estiverem ociosos por mais do que o keepAliveTime (consulte #getKeepAliveTime(TimeUnit)). Isso fornece um meio de reduzir o consumo de recursos quando o pool não está sendo usado ativamente. Se o pool se tornar mais ativo posteriormente, novos threads serão construídos. Esse parâmetro também pode ser alterado dinamicamente usando o método #setKeepAliveTime(long, TimeUnit). O uso de um valor de desabilita Long.MAX_VALUETimeUnit#NANOSECONDS efetivamente os threads ociosos da terminação anterior ao desligamento. Por padrão, a política keep-alive só se aplica quando há mais de threads corePoolSize, mas o método #allowCoreThreadTimeOut(boolean) pode ser usado para aplicar essa política de tempo limite a threads principais, desde que o valor keepAliveTime não seja zero.
</dd>
<dt>Queuing</dt>
<dd>Qualquer BlockingQueue pode ser usado para transferir e manter as tarefas enviadas. O uso dessa fila interage com o dimensionamento do pool:
<ul>
<li>Se menos de threads corePoolSize estiverem em execução, o Executor sempre preferirá adicionar um novo thread em vez de enfileirar.
<li>Se corePoolSize ou mais threads estiverem em execução, o Executor sempre preferirá enfileirar uma solicitação em vez de adicionar um novo thread.
<li>Se uma solicitação não puder ser enfileirada, um novo thread será criado, a menos que isso exceda maximumPoolSize, nesse caso, a tarefa será rejeitada.
</ul>
Há três estratégias gerais para enfil: <ol>
<li><em> entregas diretas.</em> Uma boa opção padrão para uma fila de trabalho é uma SynchronousQueue tarefa que entrega tarefas a threads sem mantê-las de outra forma. Aqui, uma tentativa de enfileirar uma tarefa falhará se nenhum thread estiver disponível imediatamente para executá-la, portanto, um novo thread será construído. Essa política evita bloqueios ao lidar com conjuntos de solicitações que podem ter dependências internas. As entregas diretas geralmente exigem maximumPoolSizes não associados para evitar a rejeição de novas tarefas enviadas. Isso, por sua vez, admite a possibilidade de crescimento de thread não associado quando os comandos continuam a chegar em média mais rápido do que podem ser processados.
<li><em> filas não associados.</em> Usar uma fila não associado (por exemplo, uma LinkedBlockingQueue sem uma capacidade predefinida) fará com que novas tarefas aguardem na fila quando todos os threads corePoolSize estiverem ocupados. Portanto, não mais do que threads corePoolSize jamais serão criados. (E o valor do maximumPoolSize, portanto, não tem nenhum efeito.) Isso pode ser apropriado quando cada tarefa é completamente independente de outras, portanto, as tarefas não podem afetar a execução umas das outras; por exemplo, em um servidor de página da Web. Embora esse estilo de enfileiramento possa ser útil na suavização de intermitências transitórias de solicitações, ele admite a possibilidade de crescimento de fila de trabalho não associado quando os comandos continuam a chegar em média mais rápido do que podem ser processados.
<li><em>Filas limitadas.</em> Uma fila limitada (por exemplo, uma ArrayBlockingQueue) ajuda a evitar o esgotamento de recursos quando usada com maximumPoolSizes finitos, mas pode ser mais difícil de ajustar e controlar. Os tamanhos de fila e os tamanhos máximos do pool podem ser trocados entre si: o uso de filas grandes e pools pequenos minimiza o uso da CPU, os recursos do sistema operacional e a sobrecarga de alternância de contexto, mas pode levar a uma taxa de transferência artificialmente baixa. Se as tarefas forem bloqueadas com frequência (por exemplo, se elas estiverem associadas à E/S), um sistema poderá agendar tempo para mais threads do que você permitir de outra forma. O uso de filas pequenas geralmente requer tamanhos de pool maiores, o que mantém as CPUs mais movimentadas, mas pode encontrar sobrecarga de agendamento inaceitável, o que também diminui a taxa de transferência.
</ol>
</dd>
<dt>Tarefas rejeitadas</dt>
<dd>Novas tarefas enviadas no método #execute(Runnable) serão <>rejeitadas</em> quando o Executor tiver sido desligado e também quando o Executor usar limites finitos para o máximo de threads e a capacidade da fila de trabalho e estiver saturado. Em ambos os casos, o execute método invoca o RejectedExecutionHandler#rejectedExecution(Runnable, ThreadPoolExecutor) método de sua RejectedExecutionHandler. Quatro políticas de manipulador predefinidas são fornecidas:
<ol>
<li>No padrão ThreadPoolExecutor.AbortPolicy, o manipulador lança um runtime RejectedExecutionException após a rejeição.
<li>In ThreadPoolExecutor.CallerRunsPolicy, o thread que se invoca execute executa a tarefa. Isso fornece um mecanismo de controle de comentários simples que reduzirá a taxa de envio de novas tarefas.
<li>In ThreadPoolExecutor.DiscardPolicy, uma tarefa que não pode ser executada é simplesmente descartada. Essa política é projetada apenas para os casos raros nos quais a conclusão da tarefa nunca é confiada.
<li>In ThreadPoolExecutor.DiscardOldestPolicy, se o executor não estiver desligado, a tarefa à frente da fila de trabalho será descartada e a execução será repetida (o que pode falhar novamente, fazendo com que isso seja repetido).) Essa política raramente é aceitável. Em quase todos os casos, você também deve cancelar a tarefa para causar uma exceção em qualquer componente aguardando sua conclusão e/ou registrar a falha em log, conforme ilustrado na ThreadPoolExecutor.DiscardOldestPolicy documentação.
</ol>
É possível definir e usar outros tipos de RejectedExecutionHandler classes. Isso requer algum cuidado, especialmente quando as políticas são projetadas para funcionar apenas sob determinada capacidade ou políticas de enfileiramento.
</dd>
<métodos< dt>Hook/dt>
<dd>Essa classe fornece protected métodos e #afterExecute(Runnable, Throwable) substituíveis #beforeExecute(Thread, Runnable) que são chamados antes e depois da execução de cada tarefa. Elas podem ser usadas para manipular o ambiente de execução; por exemplo, reinicializando ThreadLocals, coletando estatísticas ou adicionando entradas de log. Além disso, o método #terminated pode ser substituído para executar qualquer processamento especial que precise ser feito depois que o Executor for totalmente encerrado.
Se os métodos hook, callback ou BlockingQueue gerarem exceções, os threads de trabalho internos poderão, por sua vez, falhar, terminar abruptamente e possivelmente ser substituídos.</dd>
<manutenção< da fila dt>/dt>
<O Método #getQueue() dd>permite acesso à fila de trabalho para fins de monitoramento e depuração. O uso desse método para qualquer outra finalidade é altamente desencorajado. Dois métodos fornecidos #remove(Runnable) e #purge estão disponíveis para auxiliar na recuperação de armazenamento quando um grande número de tarefas enfileiradas é cancelado.</dd>
<dt>Reclamation</dt>
<dd>Um pool que não é mais referenciado em um programa <em>AND</em> não tem threads restantes pode ser recuperado (lixo coletado) sem ser desligado explicitamente. Você pode configurar um pool para permitir que todos os threads não utilizados eventualmente morram definindo os tempos de vida útil apropriados, usando um limite inferior de zero threads principais e/ou configuração #allowCoreThreadTimeOut(boolean).
</dd>
</dl>
<b>Exemplo de extensão.</b> A maioria das extensões dessa classe substitui um ou mais dos métodos de gancho protegidos. Por exemplo, aqui está uma subclasse que adiciona um recurso simples de pausa/retomada:
{@code
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();
public PausableThreadPoolExecutor(...) { super(...); }
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}}
Adicionado em 1.5.
Documentação Java para java.util.concurrent.ThreadPoolExecutor.
Partes desta página são modificações baseadas no trabalho criado e compartilhado pelo Project Open Source do Open Source e usadas de acordo com os termos descritos na Creative Commons 2.5.
Construtores
| Nome | Description |
|---|---|
| ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IRejectedExecutionHandler) |
Cria um novo |
| ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IThreadFactory, IRejectedExecutionHandler) |
Cria um novo |
| ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue, IThreadFactory) |
Cria um novo |
| ThreadPoolExecutor(Int32, Int32, Int64, TimeUnit, IBlockingQueue) |
Cria um novo |
| ThreadPoolExecutor(IntPtr, JniHandleOwnership) |
Um construtor usado ao criar representações gerenciadas de objetos JNI; chamado pelo runtime. |
Propriedades
| Nome | Description |
|---|---|
| ActiveCount |
Retorna o número aproximado de threads que estão executando tarefas ativamente. |
| Class |
Retorna a classe de runtime deste |
| CompletedTaskCount |
Retorna o número total aproximado de tarefas que concluíram a execução. |
| CorePoolSize |
Retorna o número principal de threads. -ou- Define o número principal de threads. |
| Handle |
O identificador para a instância subjacente do Android. (Herdado de Object) |
| IsShutdown | |
| IsTerminated | |
| IsTerminating |
Retornará true se esse executor estiver no processo de encerramento após |
| JniIdentityHashCode |
Um |
| JniPeerMembers |
Um |
| LargestPoolSize |
Retorna o maior número de threads que já estiveram simultaneamente no pool. |
| MaximumPoolSize |
Retorna o número máximo permitido de threads. -ou- Define o número máximo permitido de threads. |
| PeerReference |
Um |
| PoolSize |
Retorna o número atual de threads no pool. |
| Queue |
Retorna a fila de tarefas usada por esse executor. |
| RejectedExecutionHandler |
Retorna o manipulador atual para tarefas inexecutáveis. -ou- Define um novo manipulador para tarefas não reexecutáveis. |
| TaskCount |
Retorna o número total aproximado de tarefas que já foram agendadas para execução. |
| ThreadFactory |
Retorna a fábrica de threads usada para criar novos threads. -ou- Define a fábrica de threads usada para criar novos threads. |
| ThresholdClass |
Essa API dá suporte à infraestrutura do Mono para Android e não se destina a ser usada diretamente do seu código. |
| ThresholdType |
Essa API dá suporte à infraestrutura do Mono para Android e não se destina a ser usada diretamente do seu código. |
Métodos
| Nome | Description |
|---|---|
| AfterExecute(IRunnable, Throwable) |
Método invocado após a conclusão da execução do Runnable especificado. |
| AllowCoreThreadTimeOut(Boolean) |
Define a política que rege se os threads principais podem acabar e terminar se nenhuma tarefa chegar dentro do tempo de vida útil, sendo substituída se necessário quando novas tarefas chegarem. |
| AllowsCoreThreadTimeOut() |
Retornará true se esse pool permitir que os threads principais reduzam o tempo limite e terminem se nenhuma tarefa chegar dentro do tempo keepAlive, sendo substituída se necessário quando novas tarefas chegarem. |
| AwaitTermination(Int64, TimeUnit) | |
| AwaitTerminationAsync(Int64, TimeUnit) |
Um |
| BeforeExecute(Thread, IRunnable) |
Método invocado antes de executar o Runnable especificado no thread especificado. |
| Clone() |
Cria e retorna uma cópia desse objeto. (Herdado de Object) |
| Dispose() |
Um |
| Dispose(Boolean) |
Um |
| Equals(Object) |
Indica se algum outro objeto é "igual a" este. (Herdado de Object) |
| Execute(IRunnable) |
Executa a tarefa fornecida em algum momento no futuro. |
| GetHashCode() |
Retorna um valor de código hash para o objeto. (Herdado de Object) |
| GetKeepAliveTime(TimeUnit) |
Retorna o tempo de keep-alive do thread, que é a quantidade de tempo que os threads podem permanecer ociosos antes de serem encerrados. |
| InvokeAll(ICollection, Int64, TimeUnit) |
Um |
| InvokeAll(ICollection) |
Um |
| InvokeAny(ICollection, Int64, TimeUnit) |
Um |
| InvokeAny(ICollection) |
Um |
| JavaFinalize() |
Chamado pelo coletor de lixo em um objeto quando a coleta de lixo determina que não há mais referências ao objeto. (Herdado de Object) |
| NewTaskFor(ICallable) |
Retorna um |
| NewTaskFor(IRunnable, Object) |
Retorna um |
| Notify() |
Ativa um único thread que está aguardando no monitor deste objeto. (Herdado de Object) |
| NotifyAll() |
Ativa todos os threads que estão aguardando no monitor deste objeto. (Herdado de Object) |
| PrestartAllCoreThreads() |
Inicia todos os threads principais, fazendo com que eles aguardem idly pelo trabalho. |
| PrestartCoreThread() |
Inicia um thread principal, fazendo com que ele aguarde o trabalho. |
| Purge() |
Tenta remover da fila de trabalho todas as |
| Remove(IRunnable) |
Remove essa tarefa da fila interna do executor se ela estiver presente, fazendo com que ela não seja executada se ainda não tiver sido iniciada. |
| SetHandle(IntPtr, JniHandleOwnership) |
Define a propriedade Handle (Herdado de Object) |
| SetKeepAliveTime(Int64, TimeUnit) |
Define o tempo de keep-alive do thread, que é a quantidade de tempo que os threads podem permanecer ociosos antes de serem encerrados. |
| Shutdown() |
Inicia um desligamento ordenado no qual as tarefas enviadas anteriormente são executadas, mas nenhuma nova tarefa será aceita. |
| ShutdownNow() |
Tenta interromper todas as tarefas em execução ativamente, interrompe o processamento de tarefas de espera e retorna uma lista das tarefas que estavam aguardando execução. |
| Submit(ICallable) |
Um |
| Submit(IRunnable, Object) |
Um |
| Submit(IRunnable) |
Envia uma tarefa Executável para execução e retorna um Futuro que representa essa tarefa. (Herdado de AbstractExecutorService) |
| Terminated() |
Método invocado quando o Executor é encerrado. |
| ToArray<T>() |
Um |
| ToString() |
Retorna uma representação de cadeia de caracteres do objeto. (Herdado de Object) |
| UnregisterFromRuntime() |
Um |
| Wait() |
Faz com que o thread atual aguarde até ser despertado, normalmente por ser <notificado/em> ou <em>interrompido</em>.<> (Herdado de Object) |
| Wait(Int64, Int32) |
Faz com que o thread atual aguarde até que ele seja despertado, normalmente por ser <>notificado</em> ou <em>interrompido</em>, ou até que uma determinada quantidade de tempo real tenha decorrido. (Herdado de Object) |
| Wait(Int64) |
Faz com que o thread atual aguarde até que ele seja despertado, normalmente por ser <>notificado</em> ou <em>interrompido</em>, ou até que uma determinada quantidade de tempo real tenha decorrido. (Herdado de Object) |
Implantações explícitas de interface
| Nome | Description |
|---|---|
| IJavaPeerable.Disposed() |
Um |
| IJavaPeerable.DisposeUnlessReferenced() |
Um |
| IJavaPeerable.Finalized() |
Um |
| IJavaPeerable.JniManagedPeerState |
Um |
| IJavaPeerable.SetJniIdentityHashCode(Int32) |
Um |
| IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
Um |
| IJavaPeerable.SetPeerReference(JniObjectReference) |
Um |
Métodos de Extensão
| Nome | Description |
|---|---|
| AwaitTerminationAsync(IExecutorService, Int64, TimeUnit) |
Um |
| GetJniTypeName(IJavaPeerable) |
Obtém o nome JNI do tipo da instância |
| InvokeAnyAsync(IExecutorService, ICollection, Int64, TimeUnit) |
Um |
| InvokeAnyAsync(IExecutorService, ICollection) |
Um |
| JavaAs<TResult>(IJavaPeerable) |
Tente coagir a digitar |
| JavaCast<TResult>(IJavaObject) |
Executa uma conversão de tipo verificada pelo tempo de execução do Android. |
| JavaCast<TResult>(IJavaObject) |
Um |
| TryJavaCast<TResult>(IJavaPeerable, TResult) |
Tente coagir a digitar |