CodeGym/Cours Java/Module 3/Bibliothèque de concurrence Java

Bibliothèque de concurrence Java

Disponible

Multithreading en Java

La machine virtuelle Java prend en charge le calcul parallèle . Tous les calculs peuvent être effectués dans le contexte d'un ou plusieurs threads. Nous pouvons facilement configurer l'accès à la même ressource ou au même objet pour plusieurs threads, ainsi que configurer un thread pour exécuter un seul bloc de code.

Tout développeur doit synchroniser son travail avec les threads lors des opérations de lecture et d'écriture pour les ressources auxquelles plusieurs threads sont alloués.

Il est important qu'au moment d'accéder à la ressource, vous disposiez de données à jour afin qu'un autre thread puisse les modifier et que vous obteniez les informations les plus récentes. Même si nous prenons l'exemple d'un compte bancaire, tant que l'argent n'y est pas arrivé, vous ne pouvez pas l'utiliser, il est donc important d'avoir toujours des données à jour. Java a des classes spéciales pour synchroniser et gérer les threads.

Objets de fil

Tout commence par le thread principal (main), c'est-à-dire qu'au moins votre programme a déjà un thread en cours d'exécution. Le thread principal peut créer d'autres threads en utilisant Callable ou Runnable . La création ne diffère que par le résultat de retour, Runnable ne renvoie pas de résultat et ne peut pas lever une exception vérifiée. Par conséquent, vous avez une bonne occasion de créer un travail efficace avec des fichiers, mais cela est très dangereux et vous devez être prudent.

Il est également possible de programmer l'exécution des threads sur un cœur de processeur séparé. Le système peut facilement se déplacer entre les threads et exécuter un thread spécifique avec les bons paramètres : c'est-à-dire que le thread qui lit les données est exécuté en premier, dès que nous avons des données, puis nous les passons au thread qui est responsable de la validation, après cela, nous le passons au thread pour exécuter une logique métier et un nouveau thread les réécrit. Dans une telle situation, 4 threads traitent les données à tour de rôle et tout fonctionnera plus rapidement qu'un thread. Chacun de ces flux est converti en un flux de système d'exploitation natif, mais la manière dont il sera converti dépend de l'implémentation JVM.

La classe Thread est utilisée pour créer et travailler avec des threads. Il possède des mécanismes de contrôle standard, ainsi que des mécanismes abstraits, tels que des classes et des collections de java.util.concurrent .

Synchronisation des threads en Java

La communication est assurée par le partage d'accès aux objets. C'est très efficace, mais en même temps, il est très facile de se tromper en travaillant. Les erreurs se présentent dans deux cas : interférence de thread - lorsqu'un autre thread interfère avec votre thread, et erreurs de cohérence de la mémoire - cohérence de la mémoire. Pour résoudre et prévenir ces erreurs, nous avons différentes méthodes de synchronisation.

La synchronisation des threads en Java est gérée par des moniteurs, il s'agit d'un mécanisme de haut niveau qui permet à un seul thread d'exécuter un bloc de code protégé par le même moniteur à la fois. Le comportement des moniteurs est considéré en termes de verrous ; un moniteur - une serrure.

La synchronisation comporte plusieurs points importants auxquels vous devez prêter attention. Le premier point est l'exclusion mutuelle - un seul thread peut posséder le moniteur, ainsi la synchronisation sur le moniteur implique qu'une fois qu'un thread entre dans un bloc synchronisé protégé par le moniteur, aucun autre thread ne peut entrer dans le bloc protégé par ce moniteur jusqu'à ce que le le premier thread quitte le bloc synchronisé. Autrement dit, plusieurs threads ne peuvent pas accéder au même bloc synchronisé en même temps.

Mais la synchronisation n'est pas seulement une exclusion mutuelle. La synchronisation garantit que les données écrites en mémoire avant ou dans un bloc synchronisé deviennent visibles pour les autres threads synchronisés sur le même moniteur. Après avoir quitté le bloc, nous libérons le moniteur et un autre thread peut le saisir et commencer à exécuter ce bloc de code.

Lorsqu'un nouveau thread capture le moniteur, nous accédons à ce bloc de code et la possibilité de l'exécuter, et à ce moment-là, les variables seront chargées à partir de la mémoire principale. Ensuite, nous pouvons voir toutes les entrées rendues visibles par la version précédente du moniteur.

Une lecture-écriture sur un champ est une opération atomique si le champ est soit déclaré volatile soit protégé par un verrou unique acquis avant toute lecture-écriture. Mais si vous rencontrez toujours une erreur, vous obtenez une erreur de réorganisation (modification de l'ordre, réorganisation). Il se manifeste dans des programmes multithreads mal synchronisés, où un thread peut observer les effets produits par d'autres threads.

L'effet d'exclusion mutuelle et de synchronisation des threads, c'est-à-dire que leur fonctionnement correct n'est obtenu qu'en entrant un bloc ou une méthode synchronisé qui acquiert implicitement un verrou, ou en obtenant explicitement un verrou. Nous en parlerons ci-dessous. Les deux façons de travailler affectent votre mémoire et il est important de ne pas oublier de travailler avec des variables volatiles .

Champs volatils en Java

Si une variable est marquée volatile , elle est disponible globalement. Cela signifie que si un thread accède à une variable volatile , il obtiendra sa valeur avant d'utiliser la valeur du cache.

Une écriture fonctionne comme une libération de moniteur et une lecture fonctionne comme une capture de moniteur. L'accès s'effectue dans une relation de type « effectué avant ». Si vous le comprenez, tout ce qui sera visible pour le thread A lorsqu'il accède à une variable volatile est la variable du thread B. Autrement dit, vous êtes assuré de ne pas perdre vos modifications des autres threads.

Les variables volatiles sont atomiques, c'est-à-dire que lors de la lecture d'une telle variable, le même effet est utilisé que lors de l'obtention d'un verrou - les données en mémoire sont déclarées invalides ou incorrectes et la valeur de la variable volatile est à nouveau lue depuis la mémoire . Lors de l'écriture, l'effet sur la mémoire est utilisé, ainsi que lors de la libération d'un verrou - un champ volatil est écrit dans la mémoire.

Java simultané

Si vous souhaitez créer une application super efficace et multithread, vous devez utiliser les classes de la bibliothèque JavaConcurrent , qui se trouvent dans le package java.util.concurrent .

La bibliothèque est très volumineuse et a des fonctionnalités différentes, alors regardons ce qu'il y a à l'intérieur et divisons-la en quelques modules :

Java simultané

Concurrent Collections est un ensemble de collections permettant de travailler dans un environnement multithread. Au lieu du wrapper de base Collections.synchronizedList avec blocage de l'accès à l'ensemble de la collection, des verrous sont utilisés sur les segments de données ou des algorithmes sans attente sont utilisés pour lire les données en parallèle.

Files d'attente - files d'attente non bloquantes et bloquantes pour travailler dans un environnement multithread. Les files d'attente non bloquantes se concentrent sur la vitesse et le fonctionnement sans bloquer les threads. Les files d'attente bloquantes conviennent au travail lorsque vous devez "ralentir" les threads Producteur ou Consommateur . Par exemple, dans une situation où certaines des conditions ne sont pas remplies, la file d'attente est vide ou pleine, ou il n'y a pas de Consumer 'a libre.

Les synchroniseurs sont des utilitaires permettant de synchroniser les threads. Ils sont une arme puissante dans le calcul "parallèle".

Les exécuteurs sont un cadre pour la création plus pratique et facile de pools de threads, il est facile de configurer la planification de tâches asynchrones avec l'obtention de résultats.

Les verrous sont de nombreux mécanismes de synchronisation de threads flexibles par rapport aux mécanismes de base synchronized , wait , notify , notifyAll .

Les atomes sont des classes qui peuvent prendre en charge les opérations atomiques sur les primitives et les références.

Commentaires
  • Populaires
  • Nouveau
  • Anciennes
Tu dois être connecté(e) pour laisser un commentaire
Cette page ne comporte pas encore de commentaires