Qual é exatamente a diferença entre o tamanho do pool principal e o tamanho máximo do pool quando falamos em termos de ThreadPoolExecutor
?
Isso pode ser explicado com a ajuda de um exemplo?
java
asynchronous
threadpoolexecutor
user2568266
fonte
fonte
Respostas:
A partir deste post :
fonte
allowCoreThreadTimeOut(boolean)
que permite que os threads principais sejam eliminados após um determinado tempo inativo. Definir isso como verdadeiro e definircore threads
=max threads
permite que o pool de threads seja dimensionado entre 0 emax threads
.IF executando threads> corePoolSize & <maxPoolSize , crie uma nova Thread se a fila de tarefas Total estiver cheia e uma nova estiver chegando.
Documento de formulário: (se houver mais de corePoolSize, mas menos de threads maximumPoolSize em execução, um novo thread será criado apenas se a fila estiver cheia.)
Agora, pegue um exemplo simples,
Aqui, 5 é o corePoolSize - significa que Jvm criará um novo thread para uma nova tarefa para as 5 primeiras tarefas. e outras tarefas serão adicionadas à fila até que a fila fique cheia (50 tarefas).
10 é o maxPoolSize - JVM pode criar no máximo 10 encadeamentos. Significa que se já houver 5 tarefas / encadeamento em execução e a fila estiver cheia com 50 tarefas pendentes e se mais uma nova solicitação / tarefa estiver chegando na fila, a JVM criará um novo encadeamento até 10 (total de encadeamentos = 5 anteriores + 5 novos) ;
new ArrayBlockingQueue (50) = é o tamanho total da fila - ele pode enfileirar 50 tarefas nela.
quando todos os 10 threads estiverem em execução e se uma nova tarefa estiver chegando, essa nova tarefa será rejeitada.
Regras para criar Threads internamente pela SUN:
Se o número de threads for menor que corePoolSize, crie um novo Thread para executar uma nova tarefa.
Se o número de threads for igual (ou maior que) corePoolSize, coloque a tarefa na fila.
Se a fila estiver cheia e o número de encadeamentos for menor que maxPoolSize, crie um novo encadeamento para executar tarefas.
Se a fila estiver cheia e o número de threads for maior ou igual a maxPoolSize, rejeite a tarefa.
Espero, isso é útil .. e por favor me corrija se eu estiver errado ...
fonte
Do doc :
Além disso:
fonte
Se você decidir criar um
ThreadPoolExecutor
manualmente em vez de usar aExecutors
classe de fábrica, precisará criar e configurar um usando um de seus construtores. O construtor mais abrangente desta classe é:Como você pode ver, você pode configurar:
Limitando o número de tarefas na fila
Limitar o número de tarefas simultâneas em execução, dimensionar seu pool de threads representa um grande benefício para seu aplicativo e seu ambiente de execução em termos de previsibilidade e estabilidade: uma criação de thread ilimitada acabará esgotando os recursos de tempo de execução e seu aplicativo pode experimentar como consequência , sérios problemas de desempenho que podem levar até mesmo à instabilidade do aplicativo.
Essa é uma solução para apenas uma parte do problema: você está limitando o número de tarefas sendo executadas, mas não está limitando o número de trabalhos que podem ser enviados e enfileirados para execução posterior. O aplicativo apresentará escassez de recursos posteriormente, mas eventualmente ocorrerá se a taxa de envio ultrapassar consistentemente a taxa de execução.
A solução para esse problema é: Fornecer uma fila de bloqueio ao executor para manter as tarefas em espera. No caso de a fila ficar cheia, a tarefa enviada será "rejeitada". O
RejectedExecutionHandler
é chamado quando um envio de tarefa é rejeitado e é por isso que o verbo rejeitado foi citado no item anterior. Você pode implementar sua própria política de rejeição ou usar uma das políticas integradas fornecidas pela estrutura.A política de rejeição padrão faz com que o executor lance um
RejectedExecutionException
. No entanto, outras políticas integradas permitem que você:fonte
Fonte
As regras para o tamanho de uma
ThreadPoolExecutor's
piscina geralmente não são compreendidas, porque ela não funciona da maneira que você acha que deveria ou da maneira que você deseja.Veja este exemplo. O tamanho do conjunto de encadeamentos inicial é 1, o tamanho do conjunto principal é 5, o tamanho máximo do conjunto é 10 e a fila é 100.
Maneira da Sun: à medida que as solicitações chegam em threads serão criadas até 5, as tarefas serão adicionadas à fila até chegar a 100. Quando a fila estiver cheia, novos threads serão criados até
maxPoolSize
. Quando todos os threads estiverem em uso e a fila cheia, as tarefas serão rejeitadas. À medida que a fila diminui, também diminui o número de threads ativos.Forma antecipada pelo usuário: conforme as solicitações chegam em threads serão criadas até 10, as tarefas serão adicionadas à fila até chegar a 100, momento em que são rejeitadas. O número de threads será renomeado no máximo até que a fila esteja vazia. Quando a fila estiver vazia, os threads morrerão até que
corePoolSize
sobrem.A diferença é que os usuários querem começar a aumentar o tamanho do pool mais cedo e querem que a fila seja menor, enquanto o método Sun deseja manter o tamanho do pool pequeno e apenas aumentá-lo quando a carga se tornar muito.
Aqui estão as regras da Sun para a criação de threads em termos simples:
corePoolSize
, crie um novo Thread para executar uma nova tarefa.corePoolSize
, coloque a tarefa na fila.maxPoolSize
, crie um novo thread para executar tarefas.maxPoolSize
, rejeite a tarefa. Resumindo, os novos encadeamentos são criados apenas quando a fila fica cheia, portanto, se você estiver usando uma fila ilimitada, o número de encadeamentos não será superiorcorePoolSize
.Para uma explicação mais completa, pegue na boca dos cavalos:
ThreadPoolExecutor
documentação da API.Há uma postagem de fórum muito boa que mostra como
ThreadPoolExecutor
funciona com exemplos de código: http://forums.sun.com/thread.jspa?threadID=5401400&tstart=0Mais informações: http://forums.sun.com/thread.jspa?threadID=5224557&tstart=450
fonte
Você pode encontrar a definição dos termos corepoolsize e maxpoolsize no javadoc. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
O link acima tem a resposta para sua pergunta. No entanto, só para deixar isso claro. O aplicativo continuará criando threads até atingir corePoolSize. Acho que a ideia aqui é que esses muitos threads devem ser suficientes para lidar com o fluxo de entrada de tarefas. Se uma nova tarefa vier após os threads corePoolSize serem criados, as tarefas serão enfileiradas. Quando a fila estiver cheia, o executor começará a criar novos threads. É uma espécie de equilíbrio. O que essencialmente significa é que o influxo de tarefas é mais do que a capacidade de processamento. Portanto, o Executor começará a criar novos threads novamente até atingir o número máximo de threads. Novamente, um novo encadeamento será criado se e somente se a fila estiver cheia.
fonte
Boa explicação neste blog:
Ilustração
Resultado :
fonte
Do livro Java Concurency Essentials :
CorePoolSize : O ThreadPoolExecutor tem um atributo corePoolSize que determina quantos threads ele iniciará até que novos threads sejam iniciados apenas quando a fila estiver cheia
MaximumPoolSize : este atributo determina quantos threads são iniciados no máximo. Você pode definir isso como Inteiro. MAX_VALUE para não ter limite superior
fonte
java.util.concurrent.ThreadPoolExecutor
fonte
Entender o comportamento interno de
ThreadPoolExecutor
quando uma nova tarefa é enviada me ajudou a entender comocorePoolSize
e comomaximumPoolSize
diferir.Deixei:
N
ser o número de threads no poolgetPoolSize()
,. Threads ativos + threads inativos.T
ser a quantidade de tarefas submetidas ao executor / pool.C
ser o tamanho do pool principalgetCorePoolSize()
. Quantos threads podem ser criados por pool para as tarefas de entrada antes que novas tarefas vão para a fila .M
ser o tamanho máximo do poolgetMaximumPoolSize()
. Quantidade máxima de threads que o pool pode alocar.Comportamentos do
ThreadPoolExecutor
em Java quando uma nova tarefa é enviada:N <= C
, os threads ociosos não são atribuídos à nova tarefa de entrada, em vez disso, um novo thread é criado.N > C
e se houver threads inativos, uma nova tarefa é atribuída a eles.N > C
e se não houver encadeamentos ociosos, novas tarefas são colocadas na fila. NENHUMA NOVA LINHA CRIADA AQUI.M
. SeM
for alcançado, rejeitamos as tarefas. O que é importante não notar aqui é que não criamos novos threads até que a fila esteja cheia!Fontes:
Exemplos
Exemplo com
corePoolSize = 0
emaximumPoolSize = 10
com capacidade de fila de50
.Isso resultará em um único encadeamento ativo no pool até que a fila contenha 50 itens.
Exemplo com
corePoolSize = 10
emaximumPoolSize = 10
com capacidade de fila de50
.Isso resultará em 10 threads ativos no pool. Quando a fila tiver 50 itens, as tarefas serão rejeitadas.
fonte