O pool de threads é uma ferramenta prática para coletar tarefas em paralelo. Com a introdução de arquiteturas de vários núcleos adequados para a paralelização da aplicação, o papel dos pools de threads está se tornando cada vez mais aparente. Através da classe ThreadpoolExecutor e outras classes auxiliares, o Java 5 introduziu essa estrutura como uma nova seção de suporte de concorrência.
A estrutura ThreadpoolExecutor é flexível e poderosa. Ele suporta configurações específicas do usuário e fornece ganchos e políticas de saturação relevantes para lidar com filas completas.
O Java Thread Pool colocará as tarefas enviadas primeiro na fila de trabalho e as obtém da fila de trabalho (o síncrono é enviado diretamente pelo produtor ao tópico de trabalho). Depois, há duas estratégias de implementação para filas de trabalho: filas ilimitadas e filas limitadas. Não há problema com a saturação na fila ilimitada, mas o problema é que, quando a solicitação continua sendo alta, a tarefa será adicionada à fila de trabalho sem cérebro, o que pode causar memória e outros recursos. As filas limitadas não causarão a exaustão da memória causada por alta carga, mas há um problema de como gerenciar tarefas recentemente enviadas quando a fila de trabalho estiver cheia. Esse é o problema que a estratégia de saturação da fila do pool de threads precisa resolver.
As estratégias de saturação são divididas em: abortar a estratégia, a estratégia dos CallerRuns, a estratégia de descarte e a estratégia de descarte.
Para um melhor entendimento, escrevi um pequeno exemplo.
pacote concorrência.pool; importar java.util.concurrent.LinkedBlockingDequ; importar java.util.Concurrent.RejectExExecutionHandler; importar java.util.Concurrent.ThreadPoolExector; import java.util.Concurrent.TimeUnit; PublicPolicy STREAT (Classe SaturationPolicy; Diferentes políticas de saturação* Política de saturação do pool de linhas do manipulador @param* Política de void estática pública (rejeição manipulador de manipulador de manipulador) {// Existem 2 threads básicos, o número máximo de threads é 3 e a capacidade da fila de trabalho é 5. ThreadpoolExecutor Excec = New ThreadisEnmilill. LinkedBlockingDeque <> (5)); if (manipulador! = Null) {Exec.SetRejecteDexecutionHandler (manipulador); // Defina a política de saturação} para (int i = 0; i <10; i ++) {exec.submit (new Task); // levant task (} exec.shutDown () (exec.) (); Policy (new ThreadPoolExecutor.abortpolicy ()); // Policy ((new Threadpoolexecutor.CallerRunSpolicy ())); // Policy (new ThreadPoolExecutor.DiscardPolicy (); // Policy (New ThreadPoolExecutor.DiscardEstes RUNCOLICY ();}} = 0; // ID da tarefa Public Task () {id = ++ contagem;}@substituir public void run () {try {timeUnit.Seconds.sleep (3); // Dormir por 3 segundos} catch (interruptedException e) {System.err.println ("Thread foi interrompido" + e.getmessage "); Tópico: " + Thread.currentThread (). getName () +" Execução concluída ");}}} Quando a fila de trabalho está cheia, as diferentes estratégias são tratadas da seguinte forma:
1. Política de ABORT: Política padrão. Quando uma nova tarefa é enviada, a exceção desmarcada é lançada diretamente. A exceção pode ser capturada pelo chamador.
Adicione o seguinte código à função principal:
Política (new ThreadpoolExecutor.abortpolicy ());
O resultado da operação é:
O programa lança uma rejeição rejeitada e um total de 8 tarefas é executada (o pool de threads pode executar 3 tarefas no início e 5 filas são armazenadas na fila de trabalho). Quando a fila de trabalho está cheia, uma exceção é jogada diretamente e a JVM não sai (não sei por que agora). Podemos ver que todos os threads que executam tarefas são threads no pool de threads.
2. Estratégia dos CallerRuns: para o mecanismo de ajuste, nem abandonar as tarefas nem joga exceções, mas volta ao chamador. A nova tarefa não é executada no pool de threads, mas no thread chamando o Exector.
Execute na função principal:
Política ((novo ThreadpoolExecutor.CallerRunSpolicy ()));
Resultados de execução
Todas as tarefas são executadas e 2 (10 - 3 -5) tarefas são executadas com sucesso no encadeamento principal e 8 tarefas são executadas por threads no pool de threads.
3. Estratégia do Discard: As tarefas recém -enviadas são abandonadas.
Executar na função principal
Política (new ThreadpoolExecutor.discardpolicy ());
Os resultados acima mostram que nenhuma exceção é lançada, as duas novas tarefas enviadas posteriormente são descartadas e apenas as 8 primeiras (3+5) são processadas e as saídas da JVM.
4. Discardold mais estratégia: a fila é a tarefa do "chefe da equipe" e, em seguida, tente enviar uma nova tarefa. (Não é adequado para cenários de fila de trabalho como filas de prioridade)
Execute o seguinte método na função principal
Política (new ThreadPoolExecutor.discardoldestpolicy ());
Resultado em execução: existem 8 tarefas em execução no total. O programa termina. As tarefas adicionadas posteriormente são 9 e 10, enquanto as tarefas anteriores 3 e 4 são descartadas.
Resumir
O exposto acima é o conteúdo inteiro deste artigo sobre o exemplo de código da estratégia de saturação da fila do Java Threads Pool. Espero que seja útil para todos. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio a este site.