"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Multithreading: conceitos-chave para engenheiros - Parte 1

Multithreading: conceitos-chave para engenheiros - Parte 1

Publicado em 2024-11-08
Navegar:114

Multithreading : Key Concepts for Engineers - Part 1

Compreender os principais conceitos de multithreading é crucial para desenvolvedores de software, pois não apenas aprimora o conjunto de habilidades, mas também impacta diretamente o desenvolvimento de aplicativos, a escalabilidade e a qualidade geral das soluções de software.

Atomicidade

No contexto de multithreading, as operações atômicas garantem que um thread possa executar uma série de ações sem interrupção de outros threads. Vários threads podem tentar ler ou gravar dados compartilhados simultaneamente. Sem atomicidade, modificações simultâneas podem levar a resultados inconsistentes ou inesperados, comumente conhecidos como condições de corrida.

A especificação Java garante que 'leitura' e 'escrita' são operações atômicas e não suas combinações. portanto, uma operação que 'lê, adiciona 1 e depois grava o resultado' não é atômica conforme a especificação. tais operações são chamadas de operações compostas e geralmente precisam ser atômicas no contexto de seu uso em nosso código.

Exemplos de operações atômicas:

  1. Incrementando um contador: Se dois threads incrementam um contador ao mesmo tempo sem atomicidade, ambos podem ler o mesmo valor e escrever de volta o mesmo valor incrementado, levando à perda de um incremento.

  2. Atualizando uma variável compartilhada: Se um thread estiver lendo um valor enquanto outro o estiver modificando, sem atomicidade, o thread de leitura poderá obter um valor inconsistente.

Alcançando Atomicidade:

  • Classes atômicas: Muitas linguagens de programação fornecem classes atômicas (por exemplo, AtomicInteger em Java) que encapsulam operações que são garantidamente atômicas.

  • Métodos/blocos sincronizados: Em linguagens como Java, você pode usar a palavra-chave sincronizada para garantir que apenas um thread possa executar um bloco de código ou método por vez.

  • Bloqueios: uso de bloqueios explícitos (por exemplo, ReentrantLockin Java) para gerenciar o acesso a recursos compartilhados.

Benefícios

  • Desempenho: As classes em java.util.concurrent.atomic também fornecem uma abordagem sem bloqueio para garantir a segurança do thread, tornando-as uma escolha preferida em muitos cenários.
  • Simplicidade: O uso de classes atômicas simplifica o código, pois os desenvolvedores não precisam gerenciar bloqueios e podem se concentrar na lógica do programa.
  • Segurança de thread: As operações atômicas garantem que as variáveis ​​sejam atualizadas com segurança em vários threads, sem o risco de corrupção de dados ou condições de corrida.

Imutabilidade

Imutabilidade refere-se à propriedade de um objeto cujo estado não pode ser modificado após ser criado. Na programação, objetos imutáveis ​​são aqueles que, uma vez inicializados, não podem ser alterados ou modificados. Em vez de modificar um objeto imutável, um novo objeto é criado com as alterações desejadas.

Imutável significa que uma vez que o construtor de um objeto tenha concluído a execução, essa instância não pode ser alterada.

Características de objetos imutáveis

  • Sem alteração de estado: Depois que um objeto imutável é criado, seu estado (atributos ou campos) permanece constante durante todo seu tempo de vida.

  • Thread-Safe: Objetos imutáveis ​​podem ser compartilhados com segurança entre vários threads sem a necessidade de sincronização, pois não podem ser modificados.

  • Estabilidade do código hash: O código hash de um objeto imutável permanece o mesmo durante toda a sua vida útil, tornando-o adequado para uso em coleções baseadas em hash, como HashMap ou HashSet.

Alcançando a imutabilidade:

  • Uso de registros (em Java 14): Em Java, o recurso de registro fornece uma maneira concisa de criar classes de dados imutáveis.
public record ImmutablePoint(int x, int y) {}
  • Use estruturas de dados imutáveis: Utilize estruturas de dados imutáveis ​​existentes fornecidas pela linguagem de programação ou bibliotecas, como:
  1. Java: Collections.unmodifiableList(), List.of(), Set.of()

  2. C#: ImmutableList, ImmutableArray de System.Collections.Immutable

  3. Python: Tuplas são inerentemente imutáveis.

  • Usar campos finais: Declara os campos de uma classe como finais. Isso garante que os campos só possam ser atribuídos uma vez, durante a construção do objeto.

  • Sem setters: Evite fornecer métodos setter para campos mutáveis. Isso evita que o código externo altere o estado de um objeto após ele ter sido construído.

public final class ImmutablePoint {
    private final int x;
    private final int y;

    public ImmutablePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}
  • Métodos estáticos de fábrica: Em vez de fornecer um construtor público, use métodos estáticos de fábrica que retornam novas instâncias do objeto, deixando claro que o estado não pode ser alterado

  • Padrão Construtor (para objetos complexos): Para objetos que requerem muitos parâmetros, use o padrão construtor para criar objetos imutáveis. O construtor acumula os parâmetros e constrói uma instância imutável no final.

Benefícios

  • Concorrência: Se a estrutura interna de um objeto imutável for válida, ela sempre será válida. Não há chance de que diferentes threads possam criar um estado inválido nesse objeto. Conseqüentemente, objetos imutáveis ​​​​são Thread Safe.

  • Coleta de lixo: É muito mais fácil para o coletor de lixo tomar decisões lógicas sobre objetos imutáveis.

Outro

Armar-se com esse conhecimento não apenas aprimora sua capacidade de escrever código de alto desempenho, mas também prepara você para os desafios do desenvolvimento de software moderno, onde a capacidade de resposta e a escalabilidade são fundamentais. Ao continuar sua jornada no mundo do multithreading, lembre-se de que cada conceito que você dominar contribuirá para o seu crescimento como desenvolvedor e para a sua capacidade de criar aplicativos que atendam e superem as expectativas do usuário.

Fique ligado, pois nos concentraremos em fome, impasse, condição de corrida, programação de sistema operacional e muito mais no próximo artigo, que elevaria suas habilidades de programação e impulsionaria sua carreira!

Referências

Um enorme agradecimento à documentação online, à comunidade e a todos os recursos disponíveis que tornaram este artigo possível.

  1. Informativo
  2. Compreendendo os conceitos básicos de multithreading
  3. Atomicidade
  4. O que é imutável

Isenção de responsabilidade: este artigo é assistido por IA. A estrutura do artigo e a lista de ideias são 100% selecionadas e pesquisadas manualmente. Eu reviso todos os textos gerados por IA para garantir a precisão das informações e adicionar alguns contextos

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/anwaar/multithreading-key-concepts-for-engineers-part-1-4g73?1 Se houver alguma violação, entre em contato com [email protected] para excluí-la
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3