Synchronisation dans Java | Expliqué

Synchronisation dans Java | Expliqué
Lorsque nous commençons deux threads ou plus dans le même programme, il est possible que les multiples threads tentent d'accéder à la même ressource et, par conséquent, des résultats incohérents seront produits. Et afin de fournir une communication fiable entre les multiples threads, le concept de synchronisation est utilisé dans Java. Le mot-clé synchronisé de Java synchronise les actions de plusieurs threads et s'assure qu'un seul thread peut accéder à une ressource spécifique à un moment donné.

Cet article explorera les différents aspects de la synchronisation en Java et à cet égard, cet article couvrira les concepts suivants:

  • Qu'est-ce que la synchronisation en Java?
  • Pourquoi la synchronisation est-elle utilisée?
  • Pourquoi le mot-clé synchronisé est utilisé dans Java
  • Comment utiliser la synchronisation dans Java

Alors, soyons

Qu'est-ce que la synchronisation en Java?

Il s'agit d'un processus qui contrôle l'accès à plus d'un thread à toute ressource partagée et, par conséquent, évite les résultats incohérents.

Pourquoi la synchronisation est-elle utilisée?

En Java, l'objectif principal de l'utilisation de la synchronisation est d'éviter le comportement incohérent des threads et d'éviter l'interférence des threads.

Pourquoi le mot-clé synchronisé est utilisé dans Java

Synchronized est un modificateur qui peut être appliqué sur les méthodes et les blocs uniquement et ne peut pas être appliqué sur les variables et les classes. Pour comprendre ce concept

Comment utiliser la synchronisation dans Java

Nous considérerons quelques exemples pour une compréhension profonde. Initialement, nous créerons un programme Java très simple pour incrémenter la valeur du compteur. Ensuite, nous prolongerons cet exemple au scénario multithread. Peu à peu, nous nous dirigerons vers la synchronisation où nous allons apprendre pourquoi le mot-clé synchronisé est utilisé en Java?

Exemple
Dans cet exemple, nous créerons un programme simple qui a une variable comptoir et une fonction définie par l'utilisateur IncrémentValue ().

classe Counter-Class
int compteur;
public void incmentValue ()
compteur ++;


classe publique SynchronizationExample
public static void main (String [] args)
Count de classe Counter = NOUVEAU COURTERSE ();
compter.incrémentValue ();
Système.dehors.println ("Counter:" + Count.comptoir);

Chaque fois que nous invoquons le IncrémentValue () il augmentera la valeur de comptoir par 1:

La valeur du compteur est incrémentée avec succès à 1, ce qui montre la pertinence de notre programme. Si nous appelons le IncrémentValue () Méthode deux fois, puis la valeur du compteur 2. De même, il montrera la valeur du compteur comme 3 si nous appelons le IncrémentValue () Méthode trois fois comme indiqué dans l'extrait ci-dessous:

Dans l'extrait de code ci-dessus, nous avons invoqué le IncrémentValue () Méthode quatre fois, il montre donc la valeur du compteur comme 4.

Exemple
Maintenant, étendons un peu l'exemple ci-dessus où nous allons créer un fil qui appellera dix fois l'incmentValue ():

classe Counter-Class
int compteur;
public void incmentValue ()
compteur ++;


classe publique SynchronizationExample
public static void main (String [] args) lève une exception
Count de classe Counter = NOUVEAU COURTERSE ();
Thread th1 = nouveau thread (new Runnable ()
public void run ()
pour (int i = 1; i <= 10; i++)
compter.incrémentValue ();


);
TH1.commencer();
TH1.rejoindre();
Système.dehors.println ("Counter:" + Count.comptoir);

Dans la méthode de code-snippet ci-dessus (), la méthode est utilisée avec l'objet de classe de thread afin qu'un thread soit attendu jusqu'à ce que l'autre thread termine l'exécution. Le code-Snippet ci-dessus produit la sortie suivante:

À partir de la sortie, il est clair que le thread appelle le IncrémentValue () dix fois et donc la valeur du compteur est égale à dix.

Jusqu'à présent, tout va bien, considérons maintenant un environnement multithread et créons un autre fil pour voir ce qui se passera lorsque deux threads appellent la même ressource (je.e. IncrémentValue () Méthode) en même temps.

Exemple

Dans cet exemple, nous avons deux threads tous les deux appellent la méthode incrémentValue () cinq cents fois:

classe Counter-Class
int compteur;
public void incmentValue ()
compteur ++;


classe publique SynchronizationExample
public static void main (String [] args) lève une exception
Count de classe Counter = NOUVEAU COURTERSE ();
Thread th1 = nouveau thread (new Runnable ()
public void run ()
pour (int i = 1; i <= 500; i++)
compter.incrémentValue ();


);
Thread th2 = nouveau thread (new Runnable ()
public void run ()
pour (int i = 1; i <= 500; i++)
compter.incrémentValue ();


);
TH1.commencer();
TH1.rejoindre();
TH2.commencer();
TH2.rejoindre();
Système.dehors.println ("Counter:" + Count.comptoir);

Comme les deux fils appellent la contre-valeur () cinq cents fois, techniquement, la valeur de l'incrément devrait être mille. Prenons l'extrait ci-dessous pour voir ce que dit la sortie:

Au lieu de «1000», nous obtenons «753», maintenant qu'est-ce que cela signifie? Pourquoi n'avons-nous pas obtenu la valeur du comptoir en 1000?

Eh bien, c'est parce que Multithreading prend en charge le traitement parallèle et, par conséquent, il est toujours possible que les deux threads récupèrent la valeur du compteur en même temps et donc les deux obtiennent la même valeur de compteur, dans un tel cas au lieu d'incrémenter le Valeur du compteur deux fois, il n'incrémente qu'une seule fois.

Alors, comment éviter un tel scénario? Bien! Dans de tels cas, le mot-clé synchronisé sera utilisé.

Exemple
Nous utiliserons le mot-clé synchronisé avec le «IncrémentValue ()”Méthode En conséquence, un seul thread accédera au«IncrémentValue ()”Méthode en même temps. Tout le code restera le même que dans l'exemple précédent, seul le mot-clé synchronisé sera ajouté avec la méthode incmenmentValue () comme indiqué dans l'extrait:

public synchronisé vide incmenmentValue ()
compteur ++;

Maintenant, si le thread 1 travaille avec le IncrémentValue () Méthode alors le thread 2 attendra, et vice versa. Cette fois, nous obtiendrons la sortie suivante:

L'extrait ci-dessus montre l'efficacité du mot-clé «synchronisé».

Conclusion

La synchronisation est un processus qui contrôle l'accès de plus d'un thread et s'assure / vérifie qu'un seul thread peut accéder à la ressource à un moment donné. Pour atteindre la synchronisation, le mot-clé synchronisé / modificateur est utilisé et il peut être appliqué aux méthodes et aux blocs mais ne peut pas être appliqué aux variables et classes. En Java, l'objectif principal de l'utilisation de la synchronisation est d'éviter le comportement incohérent des threads et d'éviter l'interférence des threads.