Conditions de concurrence Java et sections critiques
Une condition de concurrence critique est une condition particulière qui peut survenir à l'intérieur d'une section critique. Une section critique est une section de code qui est exécutée par plusieurs threads, et l'ordre d'exécution des threads affecte les résultats de l'exécution simultanée de la section critique.
Lorsque plusieurs threads exécutent une section critique, le résultat peut être différent selon l'ordre d'exécution du thread. Cette section critique contient une condition de concurrence. Le terme désignant cette condition de concurrence vient de la métaphore selon laquelle le fil traverse la section critique et le résultat de cette course affecte le résultat de l'exécution de la section critique.
Cela peut sembler un peu compliqué, c'est pourquoi je développerai les conditions de course et les sections critiques dans les sections suivantes.
Sections critiques
L'exécution de plus d'un thread dans la même application ne causera pas de problèmes par lui-même . Des problèmes surviennent lorsque plusieurs threads accèdent à la même ressource. Par exemple, la même mémoire (variable, tableau ou objet), système (base de données, service Web) ou fichier.
En fait, des problèmes peuvent survenir si un ou plusieurs threads écrivent sur ces ressources. Il est sûr que plusieurs threads lisent la même ressource, tant que la ressource ne change pas.
Voici un exemple qui peut échouer si plusieurs threads s'exécutent simultanément :
public class Counter { protected long count = 0; public void add(long value){ this.count = this.count + value; } }
Imaginez si les threads A et B sont en cours d'exécution Exécutez le méthode add de l’instance de la même classe Counter. Il n'y a aucun moyen de savoir quand le système d'exploitation basculera entre les threads. Le code de la méthode add ne sera pas exécuté par la machine virtuelle Java en tant qu'instruction atomique distincte. Au lieu de cela, il est exécuté sous la forme d'une série de jeux d'instructions plus petits, similaires à celui-ci :
Lisez la valeur this.count de la mémoire dans le registre.
Ajoutez de la valeur au registre.
Écrivez la valeur dans le registre en mémoire.
Observez ce qui se passe lorsque les threads A et B s'exécutent de manière mixte :
this.count = 0; A: Reads this.count into a register (0) B: Reads this.count into a register (0) B: Adds value 2 to register B: Writes register value (2) back to memory. this.count now equals 2 A: Adds value 3 to register A: Writes register value (3) back to memory. this.count now equals 3
Ces deux threads veulent ajouter 2 et 3 pour contrer. Par conséquent, la valeur après l’exécution de ces deux threads doit être 5. Cependant, comme les deux threads sont entrelacés dans leur exécution, les résultats finissent par être différents.
Dans l'exemple de séquence d'exécution mentionné ci-dessus, les deux threads lisent la valeur 0 de la mémoire. Ensuite, ils ajoutent leurs valeurs respectives, 2 et 3, à cette valeur et réécrivent le résultat en mémoire. Au lieu de 5, la valeur laissée dans this.count sera la valeur que le dernier thread y a écrit. Dans l’exemple ci-dessus, il s’agit du thread A, mais il pourrait également s’agir du thread B.
Conditions de concurrence dans les sections critiques
Dans l'exemple ci-dessus, le code de la méthode add contient une section critique. Lorsque plusieurs threads exécutent cette section critique, une condition de concurrence critique se produit.
Plus formellement, cette situation de deux threads en compétition pour la même ressource, et l'ordre dans lequel les ressources sont accédées est important, est appelée une condition de concurrence. Une section de code qui provoque une condition de concurrence critique est appelée section critique.
Prévenir les conditions de concurrence
Pour éviter les conditions de concurrence, vous devez vous assurer que la section critique en cours d'exécution est exécutée en tant qu'instruction atomique. Cela signifie qu'une fois qu'un seul thread l'exécute, les autres threads ne peuvent pas l'exécuter tant que le premier thread n'a pas quitté la section critique.
Les conditions de concurrence peuvent être évitées en utilisant la synchronisation des threads dans les sections critiques. La synchronisation des threads peut être obtenue à l'aide d'un verrou de synchronisation dans le code Java. La synchronisation des threads peut également être réalisée à l'aide d'autres concepts de synchronisation, tels que des verrous ou des variables atomiques comme java.util.concurrent.atomic.AtomicInteger.
Débit de la section critique
Pour les sections critiques plus petites, un verrou de synchronisation pour l'ensemble de la section critique peut fonctionner. Cependant, pour les sections critiques plus grandes, il est plus logique de les diviser en sections critiques plus petites, permettant à plusieurs threads d'exécuter chaque section critique plus petite. Il est possible de réduire les conflits pour les ressources partagées et d'augmenter le débit de l'ensemble de la section critique.
Voici un exemple Java très simple :
public class TwoSums { private int sum1 = 0; private int sum2 = 0; public void add(int val1, int val2){ synchronized(this){ this.sum1 += val1; this.sum2 += val2; } } }
Notez comment la méthode add ajoute des valeurs aux deux variables de somme. Pour éviter les conditions de concurrence critique, la sommation effectuée en interne dispose d'un verrou de synchronisation Java. Avec cette implémentation, un seul thread à la fois peut effectuer cette sommation.
Cependant, comme les deux variables de somme sont indépendantes l'une de l'autre, vous pouvez les séparer en deux verrous de synchronisation distincts, comme ceci :
public class TwoSums { private int sum1 = 0; private int sum2 = 0; public void add(int val1, int val2){ synchronized(this){ this.sum1 += val1; } synchronized(this){ this.sum2 += val2; } } }
Notez que deux threads peuvent exécuter cette méthode d'ajout en même temps. Un thread acquiert le premier verrou de synchronisation et un autre thread acquiert le deuxième verrou de synchronisation. De cette façon, les threads attendront moins de temps entre eux.
Bien sûr, cet exemple est très simple. Dans la vie réelle, la séparation des sections critiques des ressources partagées peut être plus complexe et nécessiter une analyse plus approfondie des possibilités d'ordre d'exécution.
Ce qui précède est le contenu des conditions de course Java et des sections critiques. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

Spring Boot simplifie la création d'applications Java robustes, évolutives et prêtes à la production, révolutionnant le développement de Java. Son approche "Convention sur la configuration", inhérente à l'écosystème de ressort, minimise la configuration manuelle, allo
