Synchronisation en Java: quoi, comment et pourquoi?



Cet article sur la synchronisation en Java vous aidera à vous familiariser avec la synchronisation des programmes multithreads.

Les programmes multithreads peuvent régulièrement arriver à des situations où plusieurs tenter d'accéder à la même ressource qui produit des résultats frauduleux et surprenants. Cela peut être résolu en utilisant la synchronisation en Java. Un seul thread spécifique peut accéder à la ressource à un moment donné. Cet article vous aidera à vous familiariser avec la stratégie de synchronisation.

Je vais discuter des sujets dans cet ordre:





Commençons!

Pourquoi utiliser la synchronisation en Java?



Si vous démarrez avec au moins deux threads dans un programme, il peut y avoir un risque que plusieurs threads tentent d'accéder à la même ressource. Cela peut même créer un résultat inattendu en raison de problèmes de concurrence.

Syntaxe :

synchronized (objectidentifier) ​​{// Accéder aux variables partagées et à d'autres ressources partagées}

Par exemple, essayez d'écrire dans un fichier équivalent. Cela peut corrompre les données car l'un des threads peut remplacer les données ou lorsqu'un thread ouvre lemême fichier en même temps, un autre thread pourrait fermer le même fichier.Il est nécessaire de synchroniser l'action de plusieurs threads. Cela peut être implémenté en utilisant un concept appelé M oniteurs .



  • Chaque est associé à un moniteur, qu'un thread peut verrouiller ou déverrouiller.
  • Un seul thread à la fois peut maintenir un verrou sur un moniteur.
  • Java langage de programmation fournit un moyen très pratique de créer des threads et de synchroniser leur tâche en utilisant le Synchronisé blocs.
  • Il conserve également les ressources partagées dans ce bloc particulier.

Les blocs synchronisés en Java sont marqués du symbole Synchronisé mot-clé. Ce bloc en Java est synchronisé sur un objet.Tous les blocs qui sont synchronisés sur le même objet ne peuvent avoir qu'un seul thread en cours d'exécution à l'intérieur d'eux à la fois. Tous les autres threads qui tentent d'entrer dans le bloc synchronisé sont bloqués jusqu'à ce que le thread à l'intérieur du bloc synchronisé quitte le bloc.

Types de synchronisation

Il existe essentiellement deux types de synchronisation disponibles. Elles sont:

  1. Synchronisation des processus: L'exécution simultanée de plusieurs threads ou processus pour atteindre un état tel qu'ils s'engagent dans une certaine séquence d'actions.
  2. Synchronisation des threads: Parfois quand plus d'un filtente d'accéder à une ressource partagée, vous devez vous assurer que la ressource sera utilisée par un seul thread àun temps.

N'entrons pas dans les détails de ces types et n'essayons pas de comprendre ce que sont les verrous .

Serrures à Java

Comme je l'ai mentionné précédemment, la synchronisation est construite autour d'une entité interne connue sous le nom de fermer à clé ou moniteur . Chaque objet est associé à un verrou. Ainsi, un thread qui a besoin d'un accès cohérent aux champs d'un objet doit acquérir le verrou de l'objet avant d'y accéder, puis le libérer une fois le travail terminé.

Depuis Java 5, le package java.util.concurrent.locks contient de nombreuses implémentations de verrouillage.

Voici à quoi ressemble une serrure:

public class Lock {private boolean isLocked = false public synchronized void lock () throws InterruptedException {while (isLocked) {wait ()} isLocked = true} public synchronized void unlock () {isLocked = false notify ()}}

La méthode lock () verrouille l'instance de Lock afin que tous les threads appelant lock () soient bloqués jusqu'à ce que unlock () soit exécuté.

Multi-threading sans synchronisation

Voici un exemple simple qui imprime la valeur du compteur dans une séquence et chaque fois que nous l'exécutons, il produit un résultat différent en fonction de la disponibilité du processeur pour un thread. Regarde ça!

class Multithread {public void printCount () {try {for (int i = 5 i<0 i--) { System.out.println('Counter --- ' + i ) } } catch (Exception e) { System.out.println('Thread interrupted.') } } } class Thread extends Multithread { private Thread t private String threadName Multithread MT Thread( String name, Multithread mt) { threadName = name MT= mt } public void run() { MT.printCount() System.out.println('Thread ' + threadName + ' exiting.') } public void start () { System.out.println('Starting ' + threadName ) if (t == null) { t = new Thread (this, threadName) t.start () } } } public class TestThread { public static void main(String args[]) { Multithread MT = new Multithread() Thread t = new Thread( 'Thread - 1 ', MT) Thread t1 = new Thread( 'Thread - 2 ', MT) t.start() t1.start() // wait for threads to end try { t.join() t1.join() } catch ( Exception e) { System.out.println('Interrupted') } } }

Les résultats du programme ci-dessus sont les suivants:

Sortie - Synchronisation en Java - Edureka

Multi-threading avec synchronisation

C'est le même exemple que ci-dessus mais il imprime la valeur du compteur dans la séquence. Chaque fois que nous l'exécutons, cela produit le même résultat.

class Multithread {public void printCount () {try {for (int i = 5 i> 0 i--) {System.out.println ('Counter ---' + i)}} catch (Exception e) {System. out.println ('Thread interrompu.')}}} class Thread étend Multithread {Private Thread t private String threadName Multithread MT Thread (String name, Multithread mt) {threadName = name MT = mt} public void run () {synchronized ( MT) {MT.printCount ()} System.out.println ('Thread' + threadName + 'exiting.')} Public void start () {System.out.println ('Starting' + threadName) if (t == null) {t = new Thread (this, threadName) t.start ()}}} classe publique TestThread {public static void main (String args []) {Multithread MT = new Multithread () Thread T = new Thread ('Thread - 1 ', MT) Thread T1 = new Thread (' Thread - 2 ', MT) T.start () T1.start () // attendre la fin des threads try {T.join () T1.join ()} catch (Exception e) {System.out.println ('Interrompu')}}}

La sortie est illustrée ci-dessous:

Mot-clé synchronisé

mot-clé synchronisé marque un bloc ou une méthode comme une section critique. Une section critique est où un seul thread s'exécute à la fois, et le thread détient le verrou pour la section synchronisée. Cette synchronisé mot-clé aide à l'écriture concurrent parties de toute application. Il protège également les ressources partagées au sein du bloc.

Le mot-clé synchronized peut être utilisé avec:

Parlons du bloc de code.

Mot-clé synchronisé: un bloc de code

Syntaxe

La syntaxe générale pour écrire un bloc synchronisé est:

synchronized (lockObject) {// instructions synchronisées}

Lorsqu'un thread veut exécuter les instructions synchronisées à l'intérieur du bloc, il doit acquérir le verrou sur le moniteur de lockObject. Un seul thread peut acquérir le moniteur d'un objet de verrouillage à la fois. Ainsi, tous les autres threads doivent attendre que le thread en cours d'exécution acquière le verrou et terminer son exécution.
De cette façon, le synchronisé Le mot clé garantit qu'un seul thread exécutera les instructions de bloc synchronisé à la fois, et empêche ainsi plusieurs threads de corrompre les données partagées présentes dans le bloc.

comment fusionner des données dans un tableau

Remarque :

  • Si un thread est mis en veille (en utilisant dormir() méthode), il ne libère pas le verrou. Pendant ce temps de veille, aucun thread n'exécutera les instructions de bloc synchronisées.
  • La synchronisation Java lancera NullPointerException si l’objet de verrouillage est utilisé dans « synchronisé (verrouiller) «Est nul.

Maintenant, parlons de la méthode.

Mot-clé synchronisé: Une méthode

Syntaxe

La syntaxe générale pour écrire un méthode synchronisée est:

méthode synchronisée (paramètres) {// code synchronisé}

Ici lockObject est juste une référence à un objet dont le verrou est associé au moniteur qui représente les instructions synchronisées.

Comme pour le bloc synchronisé, un thread doit acquérir le verrou sur l'objet moniteur connecté avec la méthode synchronisée. Dans le cas d'une méthode synchronisée, l'objet de verrouillage est:

  • Objet «.class» - si la méthode donnée est statique .
  • «Cet» objet - si la méthode est non statique . «Ceci» est la référence à l’objet actuel dans lequel la méthode synchronisée est invoquée.

Le mot clé synchronisé Java est rentrant dans la nature. Cela signifie que si une méthode synchronisée appelle une autre méthode synchronisée qui nécessite le même verrou, alors le thread actuel qui détient le verrou peut entrer dans cette méthode sans acquérir le verrou.

Passons au dernier sujet de cet article et signalons les principales différences entre le mot-clé synchronized et le bloc de synchronisation.

Différence entre mot-clé synchronisé et bloc synchronisé

  • Lorsque vous utilisez un mot-clé synchronisé avec un méthode , il acquiert un verrou dans l'objet pour toute la méthode. Cela signifie qu'aucun autre thread ne peut utiliser de méthode synchronisée tant que le thread actuel qui est appelé n'a pas terminé son exécution.
  • Synchronisé bloquer acquiert un verrou dans l'objet uniquement entre parenthèses après la spécification du mot-clé synchronisé. Cela signifie qu'aucun autre thread ne peut acquérir un verrou sur l'objet déjà verrouillé jusqu'à ce que le bloc se termine. Mais d'autres threads pourront accéder au reste du code présent dans la méthode.

Cela nous amène à la fin de cet article où nous avons discuté du fonctionnement exact de la synchronisation en Java. J'espère que vous êtes clair avec tout ce qui a été partagé avec vous dans ce tutoriel.

Vérifiez par Edureka, une entreprise d'apprentissage en ligne de confiance avec un réseau de plus de 250 000 apprenants satisfaits répartis dans le monde entier. Nous sommes là pour vous aider à chaque étape de votre voyage, pour devenir une autre question d'entrevue java, nous proposons un programme conçu pour les étudiants et les professionnels qui souhaitent devenir développeur Java.

Vous avez une question pour nous? Veuillez le mentionner dans la section commentaires de cette «Synchronisation en Java ' article et nous vous répondrons dans les plus brefs délais.