Galeria de mapas mentais Mapa mental do mapa de conhecimento do sistema de simultaneidade Java (programação simultânea)
Este é um mapa mental sobre o mapa de conhecimento do sistema de simultaneidade Java (programação simultânea), incluindo fila de bloqueio, noções básicas de simultaneidade, bloqueios, modelo de memória JAVA e outros aspectos do conhecimento.
Editado em 2023-11-06 19:35:07Il s'agit d'une carte mentale sur les anévrismes intracrâniens, avec le contenu principal, notamment: le congé, l'évaluation d'admission, les mesures infirmières, les mesures de traitement, les examens auxiliaires, les manifestations cliniques et les définitions.
Il s'agit d'une carte mentale sur l'entretien de comptabilité des coûts, le principal contenu comprend: 5. Liste des questions d'entrevue recommandées, 4. Compétences de base pour améliorer le taux de réussite, 3. Questions professionnelles, 2. Questions et réponses de simulation de scénarios, 1. Questions et réponses de capacité professionnelle.
Il s'agit d'une carte mentale sur les méthodes de recherche de la littérature, et son contenu principal comprend: 5. Méthode complète, 4. Méthode de traçabilité, 3. Méthode de vérification des points, 2. Méthode de recherche inversée, 1. Méthode de recherche durable.
Il s'agit d'une carte mentale sur les anévrismes intracrâniens, avec le contenu principal, notamment: le congé, l'évaluation d'admission, les mesures infirmières, les mesures de traitement, les examens auxiliaires, les manifestations cliniques et les définitions.
Il s'agit d'une carte mentale sur l'entretien de comptabilité des coûts, le principal contenu comprend: 5. Liste des questions d'entrevue recommandées, 4. Compétences de base pour améliorer le taux de réussite, 3. Questions professionnelles, 2. Questions et réponses de simulation de scénarios, 1. Questions et réponses de capacité professionnelle.
Il s'agit d'une carte mentale sur les méthodes de recherche de la littérature, et son contenu principal comprend: 5. Méthode complète, 4. Méthode de traçabilité, 3. Méthode de vérification des points, 2. Méthode de recherche inversée, 1. Méthode de recherche durable.
Programação simultânea
Modelo de memória Java (JMM)
Mecanismo de comunicação de thread
compartilhamento de memória
Adoção Java
Mensagens
modelo de memória
Reordenar
Para o desempenho do programa, o processador e o compilador irão reordenar o programa.
doença
Os resultados da execução do programa não podem ser alterados em um ambiente de thread único.
A reordenação não é permitida se existirem dependências de dados
pergunta
A reordenação pode resultar em dados inseguros em um ambiente multithread
consistência sequencial
Modelo de referência teórica em ambiente multithread
Fornece fortes garantias de visibilidade de memória para programas
característica
Todas as operações em um thread devem ser executadas na ordem do programa
Todos os threads podem ver apenas uma única ordem de execução da operação, independentemente de o programa estar sincronizado ou não
Cada operação deve ser executada atomicamente e imediatamente visível para todos os threads
acontece antes
A teoria central do JMM garante visibilidade da memória
No JMM, se os resultados de uma operação precisam ser visíveis para outra operação, então deve haver um relacionamento acontece antes entre as duas operações.
teoria
Se uma operação acontecer antes de outra operação, os resultados da execução da primeira operação serão visíveis para a segunda operação e a ordem de execução da primeira operação será antes da segunda operação.
A existência de um relacionamento acontece antes entre duas operações não significa que elas devam ser executadas na ordem especificada pelo princípio acontece antes. Se o resultado da execução após a reordenação for consistente com o resultado da execução de acordo com o relacionamento acontece antes, então esta reordenação não é ilegal.
como se fosse serial
Todas as operações podem ser reordenadas para otimização, mas você deve garantir que os resultados da reordenação não possam ser alterados.
sincronizado
Sincronização, bloqueio pesado
princípio
sincronizado pode garantir que quando um método ou bloco de código estiver em execução, apenas um método possa entrar na seção crítica ao mesmo tempo. Também pode garantir a visibilidade da memória das variáveis compartilhadas.
bloquear objeto
Método de sincronização comum, o bloqueio é o objeto da instância atual
Método de sincronização estática, o bloqueio é o objeto de classe da classe atual
Bloco de método sincronizado, o bloqueio é o objeto entre colchetes
Mecanismo de Implementação
Cabeçalho do objeto Java
O bloqueio sincronizado é armazenado no cabeçalho do objeto Java.
Inclui duas partes de dados
Marcar palavra (campo de marcação)
Mark Word foi projetado como uma estrutura de dados não fixa para armazenar o máximo de dados possível em um espaço muito pequeno. Ele reutilizará seu próprio espaço de armazenamento de acordo com o estado do objeto.
incluir
Código hash (HashCode), idade de geração do GC, sinalizador de status de bloqueio, bloqueio mantido por thread, ID de thread tendencioso, carimbo de data/hora tendencioso
Ponteiro de classe (ponteiro de tipo)
monitor
Proprietário
Inicialmente NULL significa que nenhum thread possui atualmente o registro do monitor. Quando o thread possui o bloqueio com sucesso, o identificador exclusivo do thread é salvo. Quando o bloqueio é liberado, ele é definido como NULL.
Otimização de bloqueio
bloqueio de rotação
O thread espera por um período de tempo e não será suspenso imediatamente para ver se o thread que contém o bloqueio irá liberá-lo em breve (método cíclico)
O número de palavras giratórias é difícil de controlar (-XX:preBlockSpin)
Teoria existencial: Os threads frequentemente suspendem e acordam com uma carga pesada. Pode-se considerar que cada thread mantém o bloqueio por um curto período de tempo, e o ganho supera o ganho depois que o thread é suspenso e depois acordado.
deficiência
O número de rodadas não pode ser determinado
bloqueio de rotação adaptativo
O número de giros não é mais fixo. Ele é determinado pelo tempo de giro anterior no mesmo cadeado e pelo status do proprietário do cadeado.
Se o giro for bem-sucedido, o número de giros poderá ser aumentado. Se a aquisição do bloqueio falhar com frequência, o número de giros será reduzido.
eliminação de bloqueio
Se não houver competição de dados, a JVM eliminará o mecanismo de bloqueio
Julgamentos baseados
Escape variável
desbaste de bloqueio
Conecte várias operações consecutivas de bloqueio e desbloqueio para expandir para um bloqueio maior. Por exemplo, adquirir um bloqueio dentro de um loop for
fechadura leve
Reduza o consumo de desempenho causado por bloqueios pesados tradicionais usando mutexes de sistema operacional sem competição multi-thread.
Adquira e libere bloqueios através do CAS
base de desempenho
Para a maioria das fechaduras, não haverá competição durante todo o ciclo de vida.
deficiência
Em um ambiente multithread, sua eficiência operacional é mais lenta que a de bloqueios pesados.
bloqueio de polarização
Para minimizar caminhos desnecessários de execução de bloqueio leve, sem competição multi-thread
Evite principalmente operações CAS desnecessárias, tanto quanto possível. Se o bloqueio de competição falhar, atualize para um bloqueio leve.
volátil
característica
Visibilidade volátil: Ao ler um volátil, você sempre pode ver a gravação final nesta variável.
atomicidade volátil: volátil é atômico para uma única leitura/gravação (32 bits Long, Double), exceto para operações compostas, como i;
Mecanismo de Implementação
barreira de memória
semântica de memória
Ao escrever uma variável volátil, o JMM atualizará imediatamente o valor da variável compartilhada na memória local correspondente ao thread na memória principal.
Ao ler uma variável volátil, o JMM definirá a memória local correspondente ao thread como inválida e lerá a variável compartilhada diretamente da memória principal.
semântica do sistema operacional
Memória principal, cache (thread privado) consistente?
solução
Adicionando LOCK# ao barramento
Via protocolo de coerência de cache (protocolo MESI)
modelo de memória
Reordenar
acontece antes
DCL
Padrão singleton
DCL
Reordenar
acontece antes
solução
solução volátil
Desativar reordenação
Solução baseada na inicialização da classe
Use o mecanismo classloder para garantir que haja apenas um thread ao inicializar a instância. A JVM adquirirá um bloqueio durante a fase de inicialização da classe. Este bloqueio pode sincronizar a inicialização da mesma classe por vários threads.
Noções básicas de simultaneidade
AQS
AbstractQueuedSynchronizer, sincronizador, implementa os principais componentes básicos do JUC
Resolveu um grande número de problemas detalhados envolvidos na implementação de sincronizadores em subclasses, como obtenção de status de sincronização e fila de sincronização FIFO.
Usando o padrão de método de modelo, o AQS implementa um grande número de métodos comuns e as subclasses implementam seus métodos abstratos por meio de herança para gerenciar o status de sincronização.
Fila de sincronização CLH
Fila bidirecional FIFO, AQS depende dela para resolver o problema de gerenciamento do estado de sincronização
O primeiro nó acorda e aguarda que a fila seja adicionada ao final da fila de sincronização CLH.
Aquisição e liberação de estado síncrono
Exclusivo
Obter bloqueio
Obter status de sincronização: adquirir
AdquirirInterruptivelmente: adquirirInterruptivelmente
Aquisição de tempo limite: tryAcquireNanos
liberar bloqueio
liberar
compartilhado
Obter bloqueio
adquirirCompartilhado
liberar bloqueio
lançamentoCompartilhado
Bloqueio de thread e ativação
Quando um thread adquire o bloqueio, outros threads precisam bloqueá-lo ao adquiri-lo novamente. Quando o thread libera o bloqueio, o AQS é responsável por ativá-lo.
Suporte de bloqueio
A primitiva básica de bloqueio de thread é usada para criar bloqueios e outras classes de sincronização
Cada thread que usa LockSupport está associado a uma permissão. Se a permissão estiver disponível e puder ser usada no processo, a chamada de park() retornará imediatamente, caso contrário, poderá bloquear. Se a licença ainda não estiver disponível, você pode ligar para unpark para disponibilizá-la
estacionar(), desestacionar()
CAS
Compare And Swap, a teoria central e mais básica de todo o sistema JUC
Valor de memória V, antigo valor esperado A e valor a ser atualizado B. Se e somente se o valor do valor de memória V for igual ao antigo valor esperado A, o valor do valor de memória V será modificado para B, caso contrário, nada será ser feito.
Existem quatro parâmetros nativos
defeito
Tempo de ciclo muito longo
Apenas uma variável compartilhada pode ser garantida para ser operada atomicamente
Problema ABA
solução
número da versão
Referência Atômica Estampada
Trancar
ReentranteLock
O bloqueio reentrante é um mecanismo de sincronização recursivo sem bloqueio
Um mecanismo de bloqueio mais poderoso e flexível do que o sincronizado, que pode reduzir a probabilidade de impasse.
Dividido em bloqueio justo e bloqueio injusto
A camada inferior é implementada usando AQS e herda o AQS por meio de sincronização interna.
ReentranteReadWriteLock
Bloqueio de leitura e gravação, dois bloqueios: bloqueio compartilhado: bloqueio de leitura, bloqueio exclusivo: bloqueio de gravação
Suporta justiça, injustiça, reentrada e degradação de bloqueio
Downgrade de bloqueio: De acordo com a ordem de aquisição do bloqueio de gravação, aquisição do bloqueio de leitura e liberação do bloqueio de gravação, o bloqueio de gravação pode ser rebaixado para bloqueio de leitura.
Doença
Lock fornece Condition, que é mais detalhado e flexível para operações de espera e ativação de thread.
Uma fila de condições é mantida internamente. Quando o thread atual chama o método wait(), um nó (Node) será construído a partir do thread atual e o nó será adicionado ao final da fila.
Ferramentas de simultaneidade
Barreira Cíclica
Permite que um grupo de threads espere um pelo outro até que um ponto de barreira comum seja alcançado
Em termos leigos: deixe um grupo de threads ser bloqueado quando atingir uma barreira. A barreira não abrirá até que o último thread alcance a barreira e todos os threads interceptados pela barreira continuarão a funcionar.
A camada inferior é implementada usando a condição ReentrantLock
Cenários de aplicação
A operação de mesclagem de resultados multithread é usada para calcular dados em vários threads e, finalmente, mesclar os resultados do cálculo.
Trava de contagem regressiva
Ele permite que um ou mais threads esperem até que um conjunto de operações executadas em outros threads seja concluído.
Inicializa CountDownLatch com a contagem fornecida. Como o método countDown() é chamado, o método await é bloqueado até que a contagem atual chegue a zero. Depois disso, todos os threads em espera são liberados e todas as chamadas subsequentes para aguardar retornam imediatamente. Esse comportamento ocorre apenas uma vez – a contagem não pode ser redefinida. Se você precisar zerar a contagem, considere usar um CyclicBarrier.
Diferença da CyclicBarrier
A função de CountDownLatch é permitir que 1 ou N threads esperem que outros threads concluam a execução, enquanto CyclicBarrier permite que N threads esperem uns pelos outros;
O contador do CountDownLatch não pode ser zerado; o contador do CyclicBarrier pode ser zerado e usado, por isso é chamado de barreira cíclica.
Implementado internamente usando bloqueios compartilhados
Semáforo
sinal
Um contador que controla o acesso a vários recursos compartilhados
Conceitualmente, um semáforo mantém um conjunto de permissões. Se necessário, cada aquisição() é bloqueada até que a permissão esteja disponível e, em seguida, adquire a permissão. Cada release() adiciona uma permissão, potencialmente liberando um getter de bloqueio. No entanto, em vez de usar o objeto de licença real, o Semaphore apenas conta o número de licenças disponíveis e toma as medidas necessárias.
O semáforo Semáforo é um número inteiro não negativo (>=1). Quando um thread deseja acessar um recurso compartilhado, ele deve primeiro obter o Semáforo. Quando Semáforo > 0, obtenha o recurso e defina Semáforo - 1. Se o valor do semáforo = 0, significa que todos os recursos compartilhados foram ocupados por outros threads e o thread deve aguardar que outros threads liberem os recursos. Quando a thread libera o recurso, o semáforo é 1
Cenários de aplicação
Frequentemente usado para limitar o número de threads que podem acessar determinados recursos (físicos ou lógicos)
Implementado internamente usando bloqueios compartilhados
Permutador
Um ponto de sincronização para threads que pode emparelhar e trocar elementos em um par
Permite a troca de dados entre tarefas simultâneas. Especificamente, a classe Exchanger permite que pontos de sincronização sejam definidos entre dois threads. Quando ambos os threads atingem o ponto de sincronização, eles trocam estruturas de dados, de modo que a estrutura de dados do primeiro thread vai para o segundo thread e a estrutura de dados do segundo thread vai para o primeiro thread
outro
ThreadLocal
Uma solução para o problema de variáveis de membros em um ambiente multithread, mas não tem nada a ver com sincronização de threads. A ideia é criar uma cópia separada da variável para cada thread, de modo que cada thread possa alterar independentemente sua própria cópia da variável sem afetar as cópias correspondentes de outros threads.
ThreadLocal não é usado para resolver o problema de variáveis compartilhadas, nem existe para coordenar a sincronização de threads, mas é um mecanismo introduzido para facilitar que cada thread lide com seu próprio estado.
quatro métodos
get(): Retorna o valor na cópia do thread atual desta variável local do thread
inicialValue(): Retorna o "valor inicial" do thread atual para esta variável local do thread
remove(): Remove o valor desta variável local do thread no thread atual
set (valor T): Define o valor na cópia do thread atual desta variável local do thread para o valor especificado
ThreadLocalMap
A chave para implementar o mecanismo de isolamento de threads
Cada Thread possui uma variável de membro do tipo ThreadLocal.ThreadLocalMap interna, que é usada para armazenar uma cópia da variável ThreadLocal real.
Fornece um método para armazenar uma cópia das variáveis de cada thread usando pares chave-valor. A chave é o objeto ThreadLocal atual e o valor é a cópia da variável do thread correspondente.
tome cuidado
A instância ThreadLocal em si não armazena um valor, apenas fornece uma chave para encontrar uma cópia do valor no thread atual.
É ThreadLocal contido em Thread, não Thread contido em ThreadLocal
problema de vazamento de memória
ThreadLocalMap
chave é um valor de referência fraco é uma referência forte e não pode ser reciclada
Chame explicitamente remove()
Bifurcação/Junção
Uma estrutura para executar tarefas em paralelo é uma estrutura que divide grandes tarefas em várias tarefas pequenas e, finalmente, resume os resultados de cada tarefa pequena para obter os resultados da tarefa grande.
idéia principal
"Partição"
fork decompõe tarefas e join coleta dados
roubo de emprego
Um thread rouba tarefas de outras filas para execução
O thread que executa o bloco ajuda o thread lento a executar a tarefa e melhora a eficiência de toda a tarefa.
A fila deve usar uma fila bidirecional
classe principal
ForkJoinPool
Pool de threads para execução de tarefas
ForkJoinTask
Representa tarefas, abstração de tarefas para ForkJoinPool
ForkJoinWorkerThread
Thread de trabalho que executa tarefas
Coleções simultâneas Java
ConcurrentHashMap
CAS Synchronized garante a segurança de atualizações simultâneas. A camada inferior usa uma estrutura de armazenamento de lista vinculada de array/árvore vermelha e preta.
Classes internas importantes
Nó
par chave-valor chave-valor
ÁrvoreNode
Nó de árvore vermelho-preto
ÁrvoreBin
É equivalente a uma árvore rubro-negra. Seu método de construção é, na verdade, o processo de construção de uma árvore rubro-negra.
Nó de encaminhamento
Nó auxiliar, usado para operação de expansão ConcurrentHashMap
tamanhoCtl
Identificador de controle, usado para controlar operações de inicialização e expansão da tabela
significado
Um número negativo indica que as operações de inicialização ou expansão estão em andamento.
-1 significa inicialização
-N indica que existem N-1 threads passando por operações de expansão
Um número positivo ou 0 indica que a tabela hash não foi inicializada. Este valor indica o tamanho da inicialização ou da próxima expansão.
Operações importantes
tabela de inicialização
Método de inicialização ConcurrentHashMap
Apenas um thread pode participar do processo de inicialização, outros threads devem suspender
O construtor não executa o processo de inicialização. A inicialização é, na verdade, acionada pela operação put.
etapa
sizeCtl < 0 significa que a inicialização está em andamento e o thread está suspenso
O thread obtém a qualificação de inicialização (CAS(SIZECTL, sc, -1)) para realizar o processo de inicialização
Após a conclusão da etapa de inicialização, defina sizeCtl = 0,75 * n (o próximo limite de expansão), indicando o tamanho da próxima expansão
colocar
idéia principal
Calcule a posição do nó inserido na tabela com base no valor hash. Se a posição estiver vazia, insira-o diretamente, caso contrário, insira-o em uma lista ou árvore vinculada.
A situação real é mais complicada
etapa
A tabela é nula e o thread entra na etapa de inicialização. Se outros threads estiverem inicializando, o thread trava.
Se a posição i inserida atual for nula, significa que esta posição foi inserida pela primeira vez. Basta usar CAS para inserir o nó. Se a inserção for bem-sucedida, addCount será chamado para determinar se a expansão é necessária. Se a inserção falhar, continue combinando (girar)
Se o hash do nó == MOVED (-1), significa que um thread está se expandindo e entrará no processo de expansão.
Em outros casos, os nós são inseridos de acordo com a lista vinculada ou estrutura em árvore rubro-negra, mas este processo requer bloqueio (sincronizado)
pegar
etapa
tabela==nulo;retorna nulo
Obter da lista vinculada/nó da árvore vermelho-preto
Expansão
Expansão multithread
etapa
Construa uma nextTable cujo tamanho seja o dobro do tamanho original. Esta etapa é concluída em um ambiente de thread único.
Copie o conteúdo da tabela original para nextTable. Esta etapa permite operações multithread.
O processo de conversão de uma lista vinculada em uma árvore rubro-negra
O número de elementos na lista vinculada atinge o limite 8, então a lista vinculada é convertida em uma árvore rubro-negra
Algoritmo de árvore rubro-negra
A diferença entre 1,8 e 1,7
ConcurrentLinkedQueue
Uma fila thread-safe ilimitada baseada em nós de link, usando o princípio FIFO para classificar elementos e implementada internamente usando o algoritmo CAS
imutabilidade
O próximo do último elemento na fila é nulo
Os itens de todos os nós não excluídos na fila não podem ser nulos e podem ser percorridos a partir do nó principal.
Para que o nó seja excluído, em vez de defini-lo diretamente como nulo, primeiro defina seu campo de item como nulo (o iterador irá pular nós com item nulo)
Permitir atraso nas atualizações iniciais e finais. O que isso significa? Isso significa que cabeça e cauda nem sempre apontam para o primeiro elemento e para o último elemento (explicado mais tarde)
Invariância e variabilidade da cabeça
Invariância e variabilidade da cauda
Sutileza: CAS é usado para completar operações de dados enquanto permite inconsistência na fila, e consistência fraca é totalmente demonstrada.
ConcurrentSkipListMap
A terceira estrutura de dados de valor-chave: SkipList (lista de pulos)
Pular lista
Estrutura de árvore binária balanceada
A lista de pulos permite que os dados classificados sejam distribuídos em uma lista vinculada multicamadas, usando um número aleatório de 0-1 para determinar se os dados subirão ou não, usando um algoritmo de "troca de espaço por tempo". Um ponteiro de encaminhamento é adicionado a cada nó, e alguns nós que são impossíveis de serem envolvidos podem ser ignorados ao inserir, excluir e pesquisar, melhorando assim a eficiência.
característica
É composto por muitas camadas de estrutura e os níveis são gerados aleatoriamente através de uma certa probabilidade.
Cada nível é uma lista vinculada ordenada. O padrão é a ordem crescente. Também pode ser classificado de acordo com o Comparador fornecido na criação do mapeamento, dependendo do construtor utilizado.
A lista vinculada de nível mais baixo (Nível 1) contém todos os elementos
Se um elemento aparecer na lista vinculada do Nível i, ele também aparecerá nas listas vinculadas abaixo do Nível i.
Cada nó contém dois ponteiros, um apontando para o próximo elemento na mesma lista vinculada e outro apontando para o elemento um nível abaixo.
Localizar, excluir, adicionar
ConcurrentSkipListSet
Implementado internamente usando ConcurrentSkipListMap
atômico
classe de tipo básico
Usado para atualizar tipos básicos atomicamente
AtômicoBooleano
Tipo booleano de atualização atômica
Número inteiro atômico
Inteiro de atualização atômica
Atômico Longo
Atualização atômica longa
variedade
Atualizar um elemento em uma matriz atomicamente
AtomicIntegerArray
Atualização atômica de elementos em uma matriz inteira
AtômicoLongArray
Atualização atômica de elementos em array inteiro longo
Array de referência atômica
Atualização atômica de elementos em uma matriz de tipo de referência
tipo de referência
Se quiser atualizar múltiplas variáveis atomicamente, você precisará usar a classe fornecida por esse tipo de referência de atualização atômica.
Referência Atômica
Atualização atômica de tipos de referência
AtomicReferenceFieldUpdater
Atualização atômica de campos em tipos de referência
Referência AtômicaMarkable
Atualização atômica de tipos de referência com bits de sinalização
Classe de campo
Se precisarmos apenas de um determinado campo em uma determinada classe, precisaremos usar a atualização atômica da classe de campo
AtomicIntegerFieldUpdater
Atualizador para atualizar campos inteiros atomicamente
AtomicLongFieldUpdater
Atualizador para atualizar atomicamente campos longos
Referência Atômica Estampada
Atualização atômica do tipo de referência com número de versão
fila de bloqueio
ArrayBlockingQueue
Uma fila de bloqueio limitada FIFO implementada como uma matriz
ArrayBlockingQueue é limitado e fixo. O tamanho é confirmado durante o construtor. As alterações não são suportadas após a confirmação.
A "justiça" não é garantida em um ambiente multithread
concluir
ReentranteLock
Doença
LinkedBlockingQueue
Fila de bloqueio FIFO ilimitada baseada em link
PriorityBlockingQueue
Fila de bloqueio ilimitada com suporte prioritário
Por padrão, os elementos são classificados em ordem crescente em ordem natural. Você pode classificar os elementos especificando um Comparador.
pilha binária
Classificação
pilha máxima
O valor da chave do nó pai é sempre maior ou igual ao valor da chave de qualquer nó filho
pilha mínima
O valor da chave do nó pai é sempre menor ou igual ao valor da chave de qualquer nó filho
A operação de adição está constantemente "subindo", enquanto a operação de exclusão está constantemente "descendo"
concluir
Condição ReentrantLock
pilha binária
DelayQueue
Fila de bloqueio ilimitada que suporta aquisição atrasada de elementos
aplicativo
Cache: limpe os dados armazenados em cache que expiraram no cache
Processamento de tempo limite da tarefa
concluir
Condição ReentrantLock
Fila de prioridade classificada de acordo com o tempo de atraso: PriorityQueue
Interface atrasada
Usado para marcar objetos que devem ser executados após um determinado tempo de atraso
Esta interface requer que as classes de implementação que a implementam definam um método compareTo que forneça uma ordem consistente com o método getDelay desta interface.
Fila Síncrona
Uma fila de bloqueio sem capacidade
aplicativo
Para trocar trabalho, o thread do produtor e o thread do consumidor são sincronizados para entregar determinadas informações, eventos ou tarefas
Difícil de entender, tem dificuldade com Exchanger
LinkedTransferQueue
Fila de bloqueio ilimitada composta por lista vinculada
Equivalente a um superconjunto de ConcurrentLinkedQueue, SynchronousQueue (em modo justo), LinkedBlockingQueues ilimitados, etc.
modo preventivo
Se estiver disponível, pegue-o diretamente. Caso contrário, ele ocupará esta posição até ser obtido, expirar ou ser interrompido.
LinkedBlockingDeque
Uma fila de bloqueio bidirecional composta por uma lista vinculada
A capacidade é opcional. Você pode definir a capacidade durante a inicialização para evitar expansão excessiva. Se não for definida, a capacidade padrão será Integer.MAX_VALUE.
usar
Padrão de "roubo de emprego"
Grupo de discussão
beneficiar
Reduza o consumo de recursos
Reduza o custo de criação e destruição de threads reutilizando threads criados
Melhore a velocidade de resposta
Quando uma tarefa chega, ela pode ser executada imediatamente, sem esperar a criação do thread.
Melhore a capacidade de gerenciamento de threads
Alocação, ajuste e monitoramento unificados
Executor
Executores
A classe de fábrica estática fornece métodos de fábrica estáticos de Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, Callable e outras classes
ThreadPoolExecutor
Significado do parâmetro
corePoolSize
O número de threads principais no pool de threads
máximoPoolSize
O número máximo de threads permitidos no pool de threads
keepAliveTime
Tempo ocioso do thread
unidade
unidade de keepAliveTime
fila de trabalho
Uma fila de bloqueio usada para armazenar tarefas aguardando para serem executadas
fila de bloqueio usada
ArrayBlockingQueue
LinkedBlockingQueue
Fila Síncrona
PriorityBlockingQueue
fábrica de threads
Fábrica usada para configurar a criação de threads
DefaultThreadFactory
manipulador
RejectedExecutionHandler, estratégia de rejeição do pool de threads
Classificação
AbortPolicy: lança uma exceção diretamente, política padrão
CallerRunsPolicy: Use o thread onde o chamador está localizado para executar tarefas
DiscardOldestPolicy: descarta a tarefa mais avançada na fila de bloqueio e executa a tarefa atual
DiscardPolicy: descarta a tarefa diretamente
Classificação do pool de threads
novoFixedThreadPool
Pool de threads reutilizável com um número fixo de threads
analisar
corePoolSize é consistente com MaximumPoolSize
Usando uma fila "ilimitada" LinkedBlockingQueue
máximoPoolSize, keepAliveTime, RejeitadoExecutionHandler inválido
novoCachedThreadPool
Executor usando um único thread de trabalho
analisar
corePoolSize e maximoPoolSize são definidos como 1
Use LinkedBlockingQueue como trabalhadorQueue
novoSingleThreadExecutor
Um pool de threads que cria novos threads conforme necessário
analisar
corePoolSize está definido como 0
maxPoolSize está definido como Integer.MAX_VALUE
SynchronousQueue como WorkerQueue
Se o thread principal enviar tarefas mais rapidamente do que os threads nas tarefas do processo MaximumPool, o CachedThreadPool continuará a criar novos threads, o que pode esgotar os recursos de CPU e memória.
Envio de tarefas
Executor.execute()
ExecutorService.submit()
Execução de tarefas
Processo de implementação
Ajuste do pool de threads
Dois modelos
Monitoramento do pool de threads
ScheduledThreadPoolExecutor
Herdado de ThreadPoolExecutor
Execute a tarefa após um determinado atraso ou execute-a periodicamente
DelayQueue é usado internamente para implementá-lo e as tarefas agendadas são colocadas em DelayQueue. DelayQueue encapsula internamente PriorityQueue, que classifica ScheduledFutureTasks na fila.
Futuro
Cálculo assíncrono
Futuro
Fornecer operações
Cancelamento de tarefas de execução
Consultar se a tarefa foi concluída
Obtenha resultados de execução de tarefas
Tarefa Futura
Implemente a interface RunnableFuture, que pode ser executada como Runnable ou usada como Future para obter o valor de retorno de Callable
Implementado internamente com base em AQS