1. Introdução
O uso racional de pools de threads pode trazer três benefícios. Primeiro: reduza o consumo de recursos. Reduza o consumo causado pela criação e destruição do fio, reutilizando os threads criados. Segundo: melhore a velocidade de resposta. Quando uma tarefa chega, a tarefa pode ser executada imediatamente após a criação do thread. Terceiro: melhore a gerenciamento de threads. Os tópicos são recursos escassos. Se criados ilimitadamente, eles não apenas consumirão recursos do sistema, mas também reduzirão a estabilidade do sistema. O uso de pools de threads pode ser uma alocação, ajuste e monitoramento unificados. No entanto, para fazer uso racional de pools de threads, você deve conhecer bem seus princípios.
2. Uso do pool de threads
Os quatro tipos de threads fornecidos pelos executores 1.NewCachedThreadpool cria um pool de threads em cache. Se o comprimento do pool de threads exceder as necessidades de processamento, ele poderá reciclar de forma flexível encadeamentos ociosos. Se não houver reciclagem, crie um novo thread. 2.NewfixedThreadpool cria um pool de roscas de comprimento fixo que pode controlar o número máximo de threads simultaneamente, e o excesso de threads esperará na fila. 3.NewsCheduledThreadpool cria um pool de threads de comprimento fixo que suporta execução de tarefas cronometradas e periódicas. 4.NewsingLeThreadExecutor Cria um pool de threads de thread único, que usará apenas um thread de trabalhador exclusivo para executar tarefas, garantindo que todas as tarefas sejam executadas na ordem especificada (FIFO, LIFO, prioridade).
1.NewcachedThreadpool cria um pool de threads em cache. Se o comprimento do pool de threads exceder as necessidades de processamento, ele poderá reciclar de forma flexível encadeamentos ociosos. Se não houver reciclagem, crie um novo thread. O exemplo é o seguinte
ExecutorService ExecorService = executores.newcachedThreadpool (); for (int i = 0; i <5; i ++) {final int index = i; tente {thread.sleep (índice * 1000); } catch (interruptedException e) {e.printStackTrace (); } ExecutorService.execute (new Runnable () {@Override public void run () {System.out.println (thread.currentThread (). getName () + "," + index);}});} // Informações do console Pool-1-thread-1,0pool-1-thread-1,1pool-1-thread-1,2pool-1-thread-1,3pool-1-thread-1,42.NewfixedThreadpool cria um pool de roscas de comprimento fixo que pode controlar o número máximo de threads simultaneamente, e o excesso de threads esperará na fila. O exemplo é o seguinte
ExecutorService fIllThreadpool = executores.newfixedthreadpool (4); para (int i = 0; i <5; i ++) {final int index = i; fIllThreadpool.Execute (new Runnable () {@Override public void run () {try {System.out.println (thread.currentThread (). getName () + "," + index); thread.sleep (2000);} catch (interruptExexception); {e.PrintTack.Sleep (2000);}} (interruptExexception); Pool-1-thread-1,0pool-1-thread-2,1pool-1-thread-3,2pool-1-thread-4,3pool-1-thread-1,43.NewscheduledThreadpool Crie um pool de threads de comprimento fixo, e os exemplos de ciclos de suporte e tarefas de tempo são os seguintes
ScheduleDexecutorService ScheduledThreadpool = Executores.NewsCheduledThreadpool (5); System.out.println ("Antes:" + System.currentimemillis ()/1000); ScheduledThreadpool.schedule (new Runnable () {@Override public void run () {System.out.println ("Execução atrasada por 3 segundos:" + System.CurrentTimEmillis ()/1000);}, 3, TimeUnit.Seconds); +System.currenttimemillis ()/1000); // Informações do console antes: 1518012703AFTER: 1518012703 atrasado por 3 segundos: 1518012706system.out.println ("antes:" +System.curntimemillis ()/1000); {@Override public void run () {System.out.println ("Após o atraso de 1 segundo, execute uma vez em 3 segundos:" +System.currenttimemillis ()/1000);Mensagem de console
Antes: 1518013024
Depois: 1518013024
Após 1 segundo atraso, execute uma vez em 3 segundos: 1518013025
Após 1 segundo atraso, execute uma vez em 3 segundos: 1518013028
Após 1 segundo atraso, execute uma vez em 3 segundos: 1518013031
4.NewsingLeThreadExecutor Cria um pool de threads de thread único, que usa apenas threads trabalhadores para executar tarefas, garantindo o pedido. O exemplo é o seguinte
ExecutorService SingleThreadExecutor = Executores.NewsingleThreadExecutor (); para (int i = 0; i <10; i ++) {final int index = i; singleThreadExecutor.execute (new Runnable () {@Override public void run () {try {System.out.println (thread.currentThread (). getName () + "," + index); thread.sleep (2000);} catch (interruptException);Informações do console
Pool-1-Thread-1,0
Pool-1-Thread-1,1
Pool-1-Thread-1,2
Pool-1-Thread-1,3
Pool-1-Thread-1,4
Envie tarefas ao pool de threads. A diferença entre Execute () e Submit () na classe ThreadpoolExecutor é na verdade um método declarado no executor. É implementado no ThreadpoolExector. Este método é o método central do ThreadpoolExector. Através deste método, uma tarefa pode ser enviada ao pool de threads e entregue ao pool de threads para execução.
O método submit () é um método declarado no ExecorService. Foi implementado no abstractExecutorService. Não é reescrito no ThreadpoolExecutor. Este método também é usado para enviar tarefas ao pool de threads. No entanto, é diferente do método execute (). Ele pode retornar o resultado da execução da tarefa. Verifique a implementação do método submit () através do código -fonte e você descobrirá que é realmente o método executado () chamado, mas ele usa o futuro para obter o resultado da execução da tarefa.
/** * @THOWS rejejeTexecutionException {@IritDoc} * @Throws NullPointerException {@IritdDoc} */public Future <?> submT (Runnable Task) {if (Task == NULL) lança novo nullPonterException (); Runnablefuture <Void> ftask = newTaskfor (tarefa, nulo); executar (ftask); devolver ftask;}Fechar o pool de threads, podemos fechar o pool de threads chamando o método de desligamento ou desligamento do pool de threads, mas seus princípios de implementação são diferentes. O princípio do desligamento é simplesmente definir o estado do pool de threads para desligar o estado e interromper todos os threads que não estão executando tarefas. O princípio do desligamento é atravessar os encadeamentos do trabalhador no pool de threads e, em seguida, chamar o método de interrupção do thread um por um para interromper o thread; portanto, as tarefas que não podem responder às interrupções podem nunca ser encerradas. O ShutdownNow definirá primeiro o estado do pool de threads para parar e, em seguida, tentará interromper todos os threads que estão executando ou pausando tarefas e retornará à lista de espera para que as tarefas sejam executadas.
Enquanto um desses dois métodos de fechamento for chamado, o método Insshutdown retornará true. Quando todas as tarefas foram fechadas, isso significa que o pool de threads está fechado com sucesso. Chamar o método ISTerminaed retornará verdadeiro. Quanto a qual método devemos chamar para fechar o pool de threads, ele deve ser determinado pelas características da tarefa enviadas ao pool de threads. Geralmente, o desligamento é chamado para fechar o pool de threads. Se a tarefa não precisar ser executada, o desligamento poderá ser chamado.
3. Análise do pool de threads
Análise do processo: o principal fluxo de trabalho do pool de threads é mostrado na figura abaixo: o principal fluxo de trabalho do pool de threads java
A partir da figura acima, podemos ver que, ao enviar uma nova tarefa para o pool de threads, o fluxo de processamento do pool de threads é o seguinte:
** Análise de código fonte. ** A análise do processo acima nos permite entender intuitivamente o princípio de trabalho dos pools de threads. Vamos usar o código -fonte para ver como ele é implementado. O pool de threads executa tarefas da seguinte forma:
public void execute (comando runnable) {if (command == null) lança new nullPointerException (); int c = ctl.get (); if (workerCountOf (c) <corePoolSize) {if (addWorker (comando, true)) return; c = ctl.get (); } if (isrunning (c) && workqueue.offer (comando)) {int recheck = ctl.get (); if (! Isrunning (Recheck) && Remover (comando)) rejeitar (comando); caso contrário, if (workcountOf (recheck) == 0) addWorker (nulo, false); } else if (! addWorker (comando, false)) rejeitar (comando);} Tópico do trabalhador. Quando um pool de thread cria um fio, ele encapsula o thread em um thread trabalhador. Depois que o trabalhador executar a tarefa, ele também fará um loop infinitamente para obter tarefas na fila de trabalho para executar.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.