entrada pool de threads

O que é a piscina, que muitas vezes ouvir o pool de threads no desenvolvimento de ah, pools de conexão de banco de dados, e assim por diante.
Então, no final o que é a piscina?
É realmente muito simples, instalar uma piscina de água chamou a piscina Bem, usada para manter o pool de thread pool de threads chamada (absurdo), que criamos boas N fios são colocados dentro de uma lagoa, se necessário, iremos tomar, sem a necessidade de criar manualmente adicional

Por que usar o pool de threads

De acordo com a idéia normal é que precisamos de um fio, vá para criar um fio, então a idéia é certo, mas se você precisar de mais de N passe-o? O segmento que criou copiar o código N várias cópias? Ou usar um loop for para criar? NÃO, isso não é nada bom, mas não é bom.
Porque o segmento também tem um ciclo de vida de criação e destruição de threads terá um monte de sobrecarga nos recursos do sistema, criar uma necessidade rosca para aplicar os recursos adequados para o sistema, destruindo tópicos e vai colocar pressão sobre o coletor de lixo

Os benefícios de usar um pool de threads

  1. tempos de resposta mais rápidos, é preciso pegar o fio, não crie adicional, pode ser reutilizado.
  2. uso racional dos recursos de CPU e memória, porque o CPU e memória não são ilimitados
  3. Você pode enfiar uma gestão unificada

Aplicar cena pool de threads

No desenvolvimento real, se cinco ou mais tópicos precisa, então você deve usar o pool de threads para concluir o trabalho

Criando e parar um pool de threads

Deixe o pool de threads é criado, todos nós sabemos que os objetos em Java são todos os métodos de construção, alguns podem usar o construtor sem argumentos para criar, alguma necessidade de usar o construtor tem parâmetros para criar um pool de threads é necessário para criar os parâmetros passados ​​para o construtor, nós primeiro dar uma olhada nos parâmetros estruturais do pool de threads são algumas das coisas que o significado de que, caso contrário, como você sabe o pool de threads que você cria é que tipo de regras de funcionamento fazer

  1. corePoolSize: (int)

    核心线程数
    --------------
    在线程池创建后默认是没有线程的,当有新的任务来的之后,线程池就会创建一个新的线程去执行这个任务
    假设我们把这个参数设置为5,然后有5个任务提交了过来,就会创建5个线程去执行对应的任务
    在任务执行完成之后,这5个线程并不会被收回,而是会一直保留在线程池中,等待下一个任务的到来
    ------------------
    注意:当线程池中的线程数量少于我们设定的值时,不管之前创建的线程是否空闲,有新任务来时都会创建一个新的线程去执行
  2. WorkQueue: (BlockingQueue)

    任务存储队列
    -----------------
    任务队列有很多种:介绍常见的3种
    1.SynchronousQueue:这种队列内部是没有容量的,任务过来后会直接转交给线程去执行
    2.LinkedBlockingQueue:无界队列,没有容量限制,如果内存足够,可以无限扩展,如果线程处理任务的速度跟不上任务提交过来的速度,很容易造成内存浪费和内存溢出的现象
    3.ArrayBolockingQueue:有界队列,可以设置队列的大小
    -----------------
    在我们核心线程数都被占满并且都不空闲的时候,再有新的任务过来时,就会把新的任务存储在任务队列里面
  3. MaxPoolSize: (int)

    最大线程数
    ----------------
    线程池中最大的线程数量,什么意思呢,我们用一个案例来解释它的作用
    假设,核心线程数为5,任务队列可以存储的任务数量是100,最大线程数我们设置为10
    当我们核心线程都不空闲时,而任务队列又被堆满了,也就是我们一共提交了105个任务过来,并且一个都没有执行完
    这个时候如果再有新的任务过来,那最大线程数就派上用场了。
    这个时候,我们会额外的再去创建新的线程来执行新的任务,那额外的线程可以有多少呢
    就是最大线程数-核心线程数之后得到的数量啦
    如果线程池中的线程数量达到了最大线程数,再来新的任务,就会被拒绝
    -------------------
    注意:如果创建了额外的线程,那么会先从队列中取出位于队列头位置中的任务去执行,而不是新加进来的任务
    额外创建的线程在任务执行完之后是会被销毁的,并不会一直存在,这点跟核心线程数不同
  4. KeepAliveTime: (longo)

    存活时间
    ---------------------
    这个存活时间就是说的额外线程执行完任务,空闲的时间超过了keepAliveTime之后,就会被回收了
  5. ThreadFactory: (ThreadFactory)

    创建线程的工厂
    
  6. Manipulador: (RejectedExecutionHandler)

    拒绝策略
    

pool de threads deve ser criado manualmente ou automaticamente criado

Recomendamos criado manualmente, ele pode ser mais claro pool de threads regras de funcionamento, ao esgotamento evitar de recursos
que automaticamente criar um olhar que vai trazer a questão
para criar automaticamente está realmente usando JDK foi criado e disponibilizado para alguns dos nosso pool de threads

newFixedThreadPool (significado chinês: pool segmento fixo)

public class Main {

    public static void main(String[] args) {

        
        //创建一个newFixedThreadPool线程池,并设置它的线程数量为4
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        
        //提交一千个任务去给它执行,结果就是它会不断打印线程1-线程4的名字
        for(int i = 0 ; i < 1000 ; i ++){
            executorService.execute(new test());
        }
    }
}

//打印当前线程的名字
class test implements Runnable{

    @Override
    public void run() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
    }
}

No início dissemos, o construtor do pool de threads existem vários, Por que aqui só passar um na linha, e na frente disse, e há um número do núcleo de tópicos e o número máximo de linhas para atender certas condições irá criar tópicos adicionais, por Thread 1 só para imprimir o nome da linha 4, vamos olhar ir na fonte deste bar pool de threads

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(  nThreads,     //核心线程数
                                        nThreads,     //最大线程数
                                        0L,         //存活时间 
                                        TimeUnit.MILLISECONDS, //时间单位,这里是毫秒
                                        //任务队列,这里使用的是无界队列
                                        new LinkedBlockingQueue<Runnable>()
                                );
    }

Como pode ser visto, um novo ThreadPoolExecutor interna, dentro dos parâmetros tenho de comentar marcou um número do núcleo de tópicos e o número máximo de segmentos 4 passa este parâmetro que estão chegando, então não importa quantas tarefas entrar, não haveria no máximo há quatro tópicos execução do seu trabalho, e temos visto fila ilimitada usado aqui, as características ilimitadas fila não está a restrições de capacidade, enquanto memória suficiente, pode ser infinitamente estendido, então não importa quantas tarefas entrar, ele será armazenado na fila de tarefas ir para dentro.
Pensar cuidadosamente sobre o uso deste pool de threads que será um problema quando muitas tarefas, threads, a alça, no entanto, continuará a amontoar-se para o interior fila de tarefas, o que resultou em uma perda de memória, quando a fila é mais do que uma aplicação para o sistema quando mais memória, bem como nova submissão de trabalhos ao longo, ele irá causar um estouro de memória.
Pode-se dizer, não há um manipulador de estratégia recusou Bem, nós temos a capacidade de transformá-lo para a frente para ver o que as condições são rejeitados, quando o número do núcleo de tópicos não é suficiente, o número máximo de segmentos não é bom o suficiente, e a fila é tempo integral a nova tarefa será rejeitada, aqui é fila ilimitada usado, não há fila está cheia de tal situação um

newSingleThreadExecutor (pool de threads em separado)

public class Main {

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for(int i = 0 ; i < 1000 ; i ++){
            executorService.execute(new test());
        }
    }
}

class test implements Runnable{

    @Override
    public void run() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
    }
}

O pool de threads não passar parâmetros, a partir do significado literal olhar para fora, há apenas segmento pool de um segmento, olhamos para o código-fonte

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

Como pode ser visto, esta piscina rosca piscina e newFixedThreadPool muito semelhante, mas precisamos especificar um número núcleo de tópicos e o número máximo de threads, a necessidade de especificar, foi escrito está morto, que é um, então o princípio é como newFixedThreadPool pool de threads é a mesma coisa.

newCechedThreadPool (cache pool de threads)

public static void main(String[] args) {

        ExecutorService executorService = Executors.newCachedThreadPool();
        for(int i = 0 ; i < 1000 ; i ++){
            executorService.execute(new test());
        }
    }

Nós dirigi-lo a olhar para o seu código fonte

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, //核心线程数
                                      //最大线程数
                                      Integer.MAX_VALUE,
                                      //存活时间 
                                      60L, TimeUnit.SECONDS,
                                      //直接交换队列
                                      new SynchronousQueue<Runnable>());
    }

Podemos ver a partir de características de fonte deste pool de threads, em primeiro lugar, o número do núcleo de tópicos é 0, isto é, o número de threads no pool de threads é nenhum núcleo, ou seja, nenhuma outra thread pode sempre sobreviver, o número máximo de segmentos do tipo inteiro máximo, podemos dizer que não há limite para o número de tarefas que me seguistes, em seguida, o tempo de sobrevida foi ajustado para 60 segundos, se um segmento estiver ocioso por mais de 60 segundos será recuperado, então a fila de tarefas, a frente da fila introduzido, não há capacidade, a tarefa não será armazenada em, cada vez que uma tarefa será imediatamente tem que enfiar de manusear.
A existência deste problema pool de threads, ele vai repetidamente criar e destruir threads, desde que haja uma nova tarefa entra, ele irá criar imediatamente um segmento para executar esta tarefa, se não após a implementação de novas tarefas para ele, esperando para ser destruição (fieira).
Em segundo lugar, também é susceptível de causar um erro de estouro de memória

newScheduledThreadPool (Suporte para execução da tarefa piscina regular ou periódica segmento)

O fio usado de duas maneiras
olhamos para o primeiro

public static void main(String[] args) {

    //传入一个int类型的参数,这个参数代表线程池中核心线程的数量
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);
    
    //调用schedule方法,第一个参数是我们要执行的任务,第二个参数时间,第三个时间单位
    //就是说,线程池在间隔5秒之后去执行我们提交的任务
    executorService.schedule(new test(), 5, TimeUnit.SECONDS);

}

o segundo

public class Main {

    public static void main(String[] args) {

        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);
        
        //间隔一秒后开始执行任务,然后每隔3秒再次执行
        executorService.scheduleAtFixedRate(new test(), 1, 3, TimeUnit.SECONDS);
    }
}

O número de threads na piscina é muito mais apropriado configuração

De acordo com seus diferentes cenários de negócios têm regras diferentes

CPU tarefas de computação intensiva (computação, criptografia, hash, etc.), o número ideal de threads deve ser 1-2 vezes o núcleo da CPU do
, o número ideal tarefa tipo IO (banco de dados de leitura e escrita, alfabetização de rede, etc.) demorado de tópicos pode ser muitas vezes o número de núcleos de CPU, 10, 100 ou até mais vezes pode o

A fórmula é: Melhores Fios = núcleos de CPU * (1 + tempo médio de espera / hora de trabalho médias)

Como parar o pool de threads

desligamento: parada elegante o fio

executorService.shutdown();
当我们调用了线程池的这个方法后,线程池就知道了我们需要它停止下来,同时,它并不会再去接收新的任务了
然后线程池就会把当前正在执行的任务和任务队列中的任务都执行完后,进行停止

isShutdown

这个方法返回一个boolean值,就是当我们对线程池调用了shutdown之后,我们想知道它到底有没有接收到
就可以调用这个方法,如果接收到了,会返回一个true,否则就是false

isterminated

这个方法返回一个boolean值,这个方法用于检测,整个线程池是否已经停止工作了

awaitTermination

executorService.awaitTermination(3l,TimeUnit.SECONDS);
这个方法与isTerminated不同,这个方法是说,在我等待的这个时间内,线程池是否已经结束工作了
如果结束返回ture,否则false

shutdownNow: rosca Não à Violência

调用这个方法后,不管线程池中的任务是否还在执行,也不管任务队列中是否还有未执行的任务
线程池都会立刻停止工作,并且会把任务队列中未执行的任务进行返回

List<Runnable> runnableList = executorService.shutdownNow();

Muitas tarefas, como recusar

Negação de oportunidade

  1. Quando chamamos o método de desligamento, se houver um novo tópico no, diretamente jogado rejeitada desta tarefa
  2. Quando o número do núcleo de tópicos e o número máximo de linhas estão ocupadas, e a fila de tarefas era tempo integral, e em seguida, haverá novas tarefas a serem rejeitados aqui que a fila de tarefas é delimitada fila, capacidade limitada

estratégia rejeitado

  1. AbortPolicy: direta, rejeitar a violência, é simplesmente rude para lançar uma exceção, assim como novas tarefas? Eu não receber

  2. DiscardPolicy: silenciosamente descartado, ele não vai ir para executar uma nova tarefa, então não diga que você não executar, diretamente para a tarefa perde, nenhuma exceção é lançada

  3. DiscardOldestPolicy: TM, a fila de tarefas não está presente na tarefa mais velho a ser realizada para descarte, adicionar novas tarefas vêm em

  4. CallerRunsPolicy: thread para enviar esta tarefa para executar esta tarefa
    , digamos, o segmento principal de apresentar uma nova tarefa para o pool de threads, mas o pool de threads não pode aceitar nova tarefa, que seria o segmento principal que esta tarefa para você completá-lo, e, em seguida, o segmento principal não teve escolha senão para levar a cabo esta tarefa a si mesmos

A estratégia última negação é melhor, porque as três primeiras estratégias são com perdas, ou não realizar novas tarefas, renunciar a tarefa de idade, e as últimas derrotas não, enquanto o thread do pool é sempre ir enviar a tarefa, a tarefa foi entregue para o segmento se submetido ao Executivo, então esta discussão seria nenhum esforço para enviar uma nova tarefa, porque foi ocupada pela tarefa apresentou, e só depois que ele e outras tarefas executado, ele vamos continuar a apresentar, o que também reduz a tarefa de velocidade submetendo

família Análise Executor

Vemos no código para criar um pool de threads em frente, é ExecutorService, é executores, então o relacionamento entre eles no final o que é isso, o pool de segmentos não deve ser ThreadPoolExecutor isso? ExecutorService como é, não se preocupe, iremos detalhar abaixo

Falamos da base para o topo

  1. Executor é a parte inferior, que é um interface que existe apenas um método de: executar (comando Execut�el)

    public interface Executor {
        void execute(Runnable command);
    }
  2. ExecutorService é uma interface, e herda a interface executor, mas também aumentou o número de outros métodos

    public interface ExecutorService extends Executor {
        void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException;
    //这些方法我们在前面都已经介绍过了,这个接口声明了一些对线程池进行管理的方法
    }
  3. AbstractExecutorService é uma classe abstrata que implementa ExecutorService, mas não as interfaces ExecutorService no método de implementar porque ele próprio é uma classe abstrata, então você não pode escrever à conclusão de que existe apenas para escrever alguns dos seus exemplos de método

    public abstract class AbstractExecutorService implements ExecutorService 
    
  4. ThreadPoolExecutor: É a classe thread pool final que herda AbstractExecutorService e implementa todos os métodos da classe pai

    public class ThreadPoolExecutor extends AbstractExecutorService
    

Bem, temos claramente descritos acima, então Executores O que é, na verdade, é uma classe Executores de ferramentas, existem muitas maneiras, incluindo a criação de vários pool de threads que usamos anteriormente

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    
    这是我们前面所使用到的一种固定线程数的线程池,方法返回的是ExecutorService,
    但是实际里面返回的是ExecutorService的子类:ThreadPoolExecutor

Observe o uso do pool de threads

  1. acumulação Evite de tarefas
  2. Evite número excessivo de tópicos
  3. Necessidade de solucionar o número de segmentos, seja em linha com as expectativas, porque às vezes a linha não estiver devidamente reciclados, pode ser nossos problemas de lógica tarefa, ele tem sido incapaz de levar a tarefa estiver concluída, o segmento tem sido incapaz de parar o trabalho, etc.

Acho que você gosta

Origin www.cnblogs.com/islcz/p/12466776.html
Recomendado
Clasificación