Maison  >  Article  >  Java  >  Multithreading : concepts clés pour les ingénieurs - Partie 1

Multithreading : concepts clés pour les ingénieurs - Partie 1

DDD
DDDoriginal
2024-09-30 10:21:20230parcourir

Multithreading : Key Concepts for Engineers - Part 1

Comprendre les concepts clés du multithreading est crucial pour les développeurs de logiciels, car cela améliore non seulement l'ensemble des compétences, mais a également un impact direct sur le développement d'applications, l'évolutivité et la qualité globale des solutions logicielles.

Atomicité

Dans le contexte du multithreading, les opérations atomiques garantissent qu'un thread peut exécuter une série d'actions sans interruption de la part des autres threads. Plusieurs threads peuvent tenter de lire ou d'écrire des données partagées simultanément. Sans atomicité, les modifications simultanées peuvent conduire à des résultats incohérents ou inattendus, communément appelés conditions de concurrence.

La spécification Java garantit que « lecture » ​​et « écriture » ​​sont des opérations atomiques et non leurs combinaisons. donc une opération qui « lit, ajoute 1 puis réécrit le résultat » n'est pas atomique selon les spécifications. ces opérations sont appelées opérations composées et elles doivent généralement être atomiques dans le contexte de leur utilisation dans notre code.

Exemples d'opérations atomiques :

  1. Incrémentation d'un compteur : Si deux threads incrémentent un compteur en même temps sans atomicité, ils peuvent tous deux lire la même valeur et réécrire la même valeur incrémentée, entraînant une perte d'un incrément.

  2. Mise à jour d'une variable partagée : Si un thread lit une valeur pendant qu'un autre la modifie, sans atomicité, le thread de lecture peut obtenir une valeur incohérente.

Atteindre l'atomicité :

  • Classes atomiques : de nombreux langages de programmation fournissent des classes atomiques (par exemple, AtomicIntegerin Java) qui encapsulent des opérations garanties comme étant atomiques.

  • Méthodes/blocs synchronisés : dans des langages comme Java, vous pouvez utiliser le mot-clé synchronisé pour garantir qu'un seul thread peut exécuter un bloc de code ou une méthode à la fois.

  • Verrous : Utilisation de verrous explicites (par exemple, ReentrantLockin Java) pour gérer l'accès aux ressources partagées.

Avantages

  • Performances : Les classes de java.util.concurrent.atomic fournissent également une approche sans verrouillage pour garantir la sécurité des threads, ce qui en fait un choix privilégié dans de nombreux scénarios.
  • Simplicité : L'utilisation de classes atomiques simplifie le code, car les développeurs n'ont pas besoin de gérer les verrous et peuvent se concentrer sur la logique du programme.
  • Sécurité des threads : Les opérations atomiques garantissent que les variables sont mises à jour en toute sécurité sur plusieurs threads sans risque de corruption des données ou de conditions de concurrence.

Immuabilité

L'immuabilité fait référence à la propriété d'un objet dont l'état ne peut pas être modifié après sa création. En programmation, les objets immuables sont ceux qui, une fois initialisés, ne peuvent être modifiés ou altérés. Au lieu de modifier un objet immuable, un nouvel objet est créé avec les modifications souhaitées.

Immuable signifie qu'une fois que le constructeur d'un objet a terminé son exécution, cette instance ne peut plus être modifiée.

Caractéristiques des objets immuables

  • Aucun changement d'état : Une fois qu'un objet immuable est créé, son état (attributs ou champs) reste constant tout au long de sa durée de vie.

  • Thread-Safe : Les objets immuables peuvent être partagés en toute sécurité entre plusieurs threads sans avoir besoin de synchronisation, car ils ne peuvent pas être modifiés.

  • Stabilité du hashcode : Le hashcode d'un objet immuable reste le même tout au long de sa durée de vie, ce qui le rend adapté à une utilisation dans des collections basées sur le hachage comme HashMap ou HashSet.

Atteindre l'immuabilité :

  • Utilisation des enregistrements (en Java 14) : En Java, la fonction d'enregistrement fournit un moyen concis de créer des classes de données immuables.
public record ImmutablePoint(int x, int y) {}
  • Utiliser des structures de données immuables : Utiliser des structures de données immuables existantes fournies par le langage de programmation ou les bibliothèques, telles que :
  1. Java : Collections.unmodifiableList(), List.of(), Set.of()

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

  3. Python : Les tuples sont intrinsèquement immuables.

  • Utiliser les champs finaux : Déclarez les champs d'une classe comme finaux. Cela garantit que les champs ne peuvent être attribués qu'une seule fois, lors de la construction de l'objet.

  • Aucun setter : Évitez de fournir des méthodes setter pour les champs mutables. Cela empêche le code externe de changer l'état d'un objet après sa construction.

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;
    }
}
  • Static Factory Methods: Instead of providing a public constructor, use static factory methods that return new instances of the object, making it clear that the state cannot be changed

  • Builder Pattern (for complex objects): For objects that require many parameters, use the builder pattern to create immutable objects. The builder accumulates the parameters and constructs an immutable instance at the end.

Benefits

  • Concurrency: If the internal structure of an immutable object is valid, it will always be valid. There's no chance that different threads can create an invalid state within that object. Hence, immutable objects are Thread Safe.

  • Garbage collection: It's much easier for the garbage collector to make logical decisions about immutable objects.

Outro

Arming yourself with this knowledge not only enhances your ability to write high-performance code but also prepares you for the challenges of modern software development, where responsiveness and scalability are paramount. As you continue your journey into the world of multithreading, remember that each concept you master will contribute to your growth as a developer and your capacity to create applications that meet and exceed user expectations.

Stay tuned as we will focus on starvation, deadlock, race-condition, OS scheduling and much more in upcoming write-up, that would elevate your programming skills and boost your career!

References

A huge thanks to the online documentation, community and all the resources available that made this write-up possible.

  1. Info-graphic
  2. Understanding Basic Multithreading Concepts
  3. Atomicity
  4. What is immutable

Disclaimer: This article is AI-assisted. The article structure and idea list are 100% manually curated and researched. I proofread all AI-generated texts to ensure information accuracy and to add some contexts

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn