Problemas básicos comuns de "programação simultânea Java"

Processo e discussão?

processo?

  • Um processo é um processo de execução de um programa, a unidade básica do sistema para executar um programa , e o processo é dinâmico.
  • O sistema que executa um programa é o processo de um processo desde a criação, operação até a morte.

Em Java, quando a função principal é iniciada, um processo JVM é realmente iniciado e o encadeamento onde a função principal está localizada é o encadeamento principal do processo.

Fio?

Um thread é um processo do que uma unidade menor de execução.

Um processo gera vários threads durante sua execução, e vários threads do mesmo tipo compartilham o heap do processo e os recursos da área de método . Cada thread tem seu próprio contador de programa, pilha de máquina virtual e pilha de método local.

Quando o sistema gera um thread ou alterna o trabalho entre os threads, a carga é muito menor do que a do processo , portanto, a thread também é chamada de processo leve.

Os programas Java são programas inerentemente multiencadeados, você pode verificar por meio do JMX:

public class Main {

    public static void main(String[] args) {
        // 获取 Java 线程管理 MXBean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        // 不需要获取同步的 monitor 和 synchronizer 信息,仅获取线程和线程堆栈信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false,false);
        // 遍历线程信息,仅打印线程 ID 和线程名称信息 和 线程状态
        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println("[" + threadInfo.getThreadId() + "]" + threadInfo.getThreadName() + "->" + threadInfo.getThreadState());
        }
    }
    
}

O resultado é o seguinte:

[6]Monitor Ctrl-Break->RUNNABLE //这是IDEA特有的监控线程
[5]Attach Listener->RUNNABLE //添加事件
[4]Signal Dispatcher->RUNNABLE  // 分发处理给 JVM 信号的线程
[3]Finalizer->WAITING    //清除 reference 线程
[2]Reference Handler->WAITING  //清除 reference 线程
[1]main->RUNNABLE //main线程,程序入口

Um programa Java deve ser executado com o thread principal e vários threads em execução ao mesmo tempo.

Concorrência e paralelismo?

  • Simultaneidade:  várias tarefas são executadas ao mesmo tempo (não necessariamente executadas ao mesmo tempo por unidade de tempo);
  • Paralelo:  Várias tarefas são executadas simultaneamente em tempo de unidade.

 

Fale sobre a relação entre processo e encadeamento a partir da perspectiva da JVM

Um processo pode ter vários threads, e vários threads compartilham os recursos do heap do processo e da área de método [metaspace após JDK1.8], mas cada thread tem seu próprio contador de programa independente, pilha de máquina virtual e pilha de método local .

Pode desenhar:

  • Um thread é uma unidade operacional menor dividida em um processo. A maior diferença entre um thread e um processo é que cada processo é basicamente independente, mas cada thread não é necessariamente. Os threads no mesmo processo podem afetar uns aos outros.
  • A sobrecarga de execução do thread é pequena, mas não conduz ao gerenciamento e proteção de recursos, enquanto o processo é exatamente o oposto.

Por que o contador do programa é privado?

A função do contador do programa:

  • O interpretador de bytecode lê instruções sequencialmente alterando o contador do programa, realizando assim o controle do fluxo do código, como execução sequencial, seleção, loop e tratamento de exceção.
  • No caso de multithreading, o contador do programa é usado para registrar a posição da execução da thread atual, de forma que quando a thread for comutada de volta, seja possível saber onde a thread foi executada pela última vez .

Deve-se notar que se o método nativo for executado, o contador do programa registra o endereço indefinido, somente quando o código Java é executado, o contador do programa registra o endereço da próxima instrução.

Resumo: O contador de programa privado é usado principalmente para restaurar a posição de execução correta após a troca de thread .

Por que a pilha da máquina virtual e a pilha do método local são privadas?

  • Pilha de máquina virtual: quando  cada método Java é executado, um frame de pilha é criado para armazenar a tabela de variáveis ​​locais, pilha de operandos, referência de pool constante e outras informações. O processo desde a chamada do método até a conclusão da execução corresponde ao processo de enviar e enviar um quadro de pilha na pilha da máquina virtual Java.
  • Pilha de método nativo:  a função desempenhada pela pilha de máquina virtual é muito semelhante. A diferença é: a  pilha de máquina virtual serve à máquina virtual para executar métodos Java (ou seja, bytecode), enquanto a pilha de método local serve os métodos nativos usados ​​pela máquina virtual .  A máquina virtual HotSpot e a pilha da máquina virtual Java são combinadas em uma.

Resumo: a pilha da máquina virtual e a pilha do método local são privadas para garantir que as variáveis ​​locais no encadeamento não sejam acessadas por outros encadeamentos .

Uma frase simples para entender a área de heap e método

O heap e a área do método são recursos compartilhados por todos os threads. O heap é a maior parte da memória no processo. É usado principalmente para armazenar objetos recém-criados [quase todos os objetos são alocados na memória aqui], e a área do método é usada principalmente para armazenar os carregados Dados como informações de classe, constantes, variáveis ​​estáticas e código compilado pelo compilador just-in-time.

Por que usar multithreading? Qual é a utilidade de multithreading?

Do geral :

  • Do fundo do computador: um thread pode ser comparado a um processo leve, a menor unidade de execução de programa, e o custo de comutação e agendamento entre threads é muito menor do que o de um processo . Além disso, a era da CPU de vários núcleos significa que vários threads podem ser executados ao mesmo tempo , o que reduz a sobrecarga da troca de contexto de thread.
  • Da perspectiva das tendências contemporâneas de desenvolvimento da Internet: o sistema atual requer milhões ou mesmo dezenas de milhões de simultaneidade em cada turno, e a programação simultânea multi-threaded é a base para o desenvolvimento de sistemas de alta simultaneidade. O uso de mecanismos multi-threaded pode melhorar muito a simultaneidade geral do sistema. Habilidade e desempenho .

Vá até a parte inferior do computador para discutir:

  • Era de núcleo único: Na era de núcleo único, o multithreading é principalmente para melhorar a utilização abrangente de dispositivos de CPU e IO. Quando há apenas um thread, isso fará com que o dispositivo IO fique ocioso quando a CPU faz o cálculo; ao executar operações IO, a CPU fica ociosa. Podemos simplesmente dizer que a utilização de ambos está atualmente em torno de 50%. Mas quando há dois threads, é diferente.Quando um thread realiza cálculos de CPU, o outro thread pode realizar operações de IO, de forma que a utilização dos dois pode chegar a 100% em condições ideais.
  • Era Multi-core: Multi-threading na era multi-core é principalmente para melhorar a utilização da CPU. Se quisermos calcular uma tarefa complexa e usarmos apenas um thread, apenas um núcleo de CPU da CPU será usado, e a criação de vários threads permitirá que vários núcleos de CPU sejam usados, aumentando assim a utilização da CPU .

Que problemas podem ser causados ​​pelo uso de multithreading?

  • Vazamento de memória
  • Impasse
  • Tópico inseguro

Visualização recomendada: Portal

O ciclo de vida e o estado do segmento?

Seis estados

Explicação do estado do thread NEW O estado do thread que não foi iniciado, ou seja, o thread foi criado e o método de início não foi chamado. RUNNABLE Estado Pronto (início da chamada, aguardando agendamento) + Running BLOCKED enquanto aguarda o bloqueio do monitor , o thread no estado bloqueado WAITING esperando por outro Um thread executa uma operação específica (como notificação) TIMED_WAITING um estado de espera com um tempo de espera especificado TERMINATED thread termina a execução, estado de término

Mudança de estado

 

Observação: o método de junção é um método da classe Thread. Está escrito como Object na figura e deve ser alterado para Thread.join.

Depois que o thread for criado, ele estará no estado NOVO (novo) começará a ser executado após chamar o método start (). O thread está agora no estado  READY (executável)  . O thread no estado executável está no  estado RUNNING após obter a fatia de tempo da CPU (timeslice)  .

Quando a thread executa o método wait (), a thread entra no estado  WAITING (em espera)  . Um encadeamento que entra no estado de espera precisa contar com notificações de outros encadeamentos para retornar ao estado de execução, e o   estado TIME_WAITING é equivalente a adicionar um limite de tempo limite ao estado de espera, como por meio do método sleep (long millis) ou wait (long milis) pode colocar o encadeamento Java no estado TIMED WAITING. Quando o tempo limite expirar, o encadeamento Java retornará ao estado RUNNABLE. Quando o encadeamento chama o método de sincronização, o encadeamento entra no estado BLOCKED (bloqueado) sem adquirir o bloqueio   . A thread entrará no estado TERMINATED (terminado) após executar o método run () de Runnable   .

O que é a troca de contexto?

Na programação multi-threaded, o número de threads geralmente é maior do que o número de núcleos da CPU, e um núcleo da CPU só pode ser usado por um thread por vez . Para permitir que esses threads sejam executados com eficácia, a CPU adota uma estratégia para cada thread A forma de alocar fatias de tempo e rotação. Quando a fração de tempo de um encadeamento se esgota, ele estará no estado pronto novamente para ser usado por outros encadeamentos Este processo é uma troca de contexto.

Resumindo: a tarefa atual salvará seu estado antes de alternar para outra tarefa após executar a fatia de tempo da CPU, de modo que o estado desta tarefa possa ser carregado novamente quando voltar para esta tarefa na próxima vez. O processo de salvar até recarregar uma tarefa é uma troca de contexto .

A comutação de contexto geralmente é computacionalmente intensiva . Em outras palavras, requer uma quantidade considerável de tempo do processador. Em dezenas ou centenas de comutações por segundo, cada comutação leva nanossegundos. Portanto, a troca de contexto significa consumir muito tempo da CPU do sistema.Na verdade, pode ser a operação mais demorada do sistema operacional.

Comparado com outros sistemas operacionais (incluindo outros sistemas semelhantes ao Unix), o Linux tem muitas vantagens, uma das quais é que ele consome muito pouco tempo para a troca de contexto e de modo.

O que é conflito de thread e como evitá-lo?

Vários threads são bloqueados ao mesmo tempo, um ou todos eles estão aguardando a liberação de um recurso.

Amigos que estudaram sistemas operacionais sabem que as quatro condições a seguir devem ser atendidas para produzir um impasse:

  1. Condição mutuamente exclusiva : o recurso é ocupado por apenas um encadeamento por vez.
  2. Condições de solicitação e retenção : Quando um processo é bloqueado pela solicitação de recursos, ele mantém os recursos adquiridos.
  3. Condições de não privação : Os recursos que um encadeamento adquiriu não podem ser privados à força por outros encadeamentos antes de serem usados, e os recursos são liberados somente depois de serem usados.
  4. Condição de espera circulante : Uma espécie de relação de recurso de espera cíclica é formada entre vários processos.

Como evitar o deadlock do thread?

Mencionei as quatro condições necessárias para o deadlock. Para evitar o deadlock, precisamos apenas destruir uma das quatro condições para o deadlock. Agora vamos analisar um por um:

  1. Destruir a condição mutuamente exclusiva  : Não temos como destruir essa condição, porque nossos usuários originalmente queriam que fossem mutuamente exclusivos (recursos críticos requerem acesso exclusivo).
  2. Solicitação de destruição e condições de retenção  : aplique para todos os recursos de uma vez.
  3. Condições de destruição e não privação  : Quando um encadeamento que ocupa alguns recursos se aplica ainda mais a outros recursos, se o aplicativo falhar, ele pode liberar ativamente os recursos que ocupa.
  4. Destrua as condições de espera do ciclo  : evite solicitando recursos sob demanda. Inscreva-se para obter recursos em uma determinada ordem e libere recursos na ordem inversa. Destrua a condição de espera do loop.

Fale sobre a diferença e semelhança entre os métodos sleep () e wait ()?

  • As duas principais diferenças são que o método sleep não libera o bloqueio, enquanto o método wait () libera o bloqueio.
  • Ambos podem suspender a execução de threads.
  • Wait geralmente é usado para interação / comunicação entre threads, e sleep é geralmente usado para suspender a execução.
  • Depois que o método wait () é chamado, o encadeamento não será ativado automaticamente e outros encadeamentos precisam chamar o método notificar () ou notificarAll () no mesmo objeto. Depois que o método sleep () for executado, a thread será ativada automaticamente. Ou você pode usar wait (long timeout) para ativar automaticamente o thread após o tempo limite.

Por que executamos o método run () quando chamamos o método start (), por que não podemos chamar o método run () diretamente?

Esta é outra pergunta de entrevista multi-threaded java muito clássica, e é freqüentemente feita durante a entrevista. É simples, mas muita gente não saberá responder!

new a Thread, a thread entra em um novo estado; chamar o método start () iniciará uma thread e fará com que a thread entre no estado pronto e pode começar a ser executada quando a fatia de tempo for alocada. start () executará o trabalho de preparação correspondente do thread e, em seguida, executará automaticamente o conteúdo do método run (), que é um trabalho verdadeiramente multi-threaded. Ao executar diretamente o método run (), o método run será executado como um método normal no thread principal e não será executado em um thread, portanto, este não é um trabalho multithread.

Resumo: Chame o método start para iniciar o thread e fazer com que o thread entre no estado pronto, enquanto o método run é apenas uma chamada de método comum de thread ou é executado no thread principal.

Se você acha que este artigo é útil para você, você pode curtir e segui-lo para apoiá-lo, ou pode seguir minha conta pública. Há mais artigos técnicos sobre produtos secos e informações relacionadas compartilhando sobre ele, todos aprendem e progridem juntos!

 

Acho que você gosta

Origin blog.csdn.net/weixin_50205273/article/details/108681994
Recomendado
Clasificación