[synchronized]quand et pourquoi l'utiliser
Résolu
ajp55
Messages postés
426
Date d'inscription
Statut
Membre
Dernière intervention
-
ajp55 Messages postés 426 Date d'inscription Statut Membre Dernière intervention -
ajp55 Messages postés 426 Date d'inscription Statut Membre Dernière intervention -
A voir également:
- [synchronized]quand et pourquoi l'utiliser
- Utiliser chromecast - Guide
- Utiliser iphone comme webcam - Guide
- Utiliser tablette comme deuxieme ecran - Guide
- Comment utiliser utorrent - Télécharger - Téléchargement & Transfert
- Comment utiliser wetransfer - Guide
1 réponse
Un programme Java peut exécuter plusieurs threads, ce sont des fils d'exécutions qui se déroulent en parallèle (c'est à dire "en même temps").
Prenons un exemple : tu as deux threads qui font la même chose en même temps.
Ils lisent la valeur de "n", lui ajoute 1, et stocke le résultat dans "m".
Puis ils attendent un petit peu (pour simuler une charge de travail)
Enfin, ils mettent à jour "n" avec la valeur de "m", et affiche la nouvelle valeur.
Les deux Threads recommencent chacun cette opération 100 fois.
Le résultat attendu pour ce calcul est donc de voir s'afficher 1, 2, 3, 4... 199, et 200.
Or ce n'est pas cela qu'on obtient !
En effet, les deux threads s'exécutent en parallèle, mais ils se partagent la même variable de n, il peut donc y avoir des conflits.
Exemple : le premier thread lit "n=12" ce qui donne "m=13". Mais en même temps, le deuxième thread lit lui aussi "n=12" ce qui donne aussi "m=13". Ils vont donc tous les deux mettre à jour "n" avec la valeur 13, alors que l'on aurait voulu avoir 14.
Comment résoudre le problème ?
Tout simplement en ajoutant le mot clé "synchronized" à la méthode add, cela va restreindre l'accès à la méthode à un seul thread à la fois. Si un thread est en train d'exécuter la méthode add, le deuxième thread qui va vouloir y rentrer va être mis en attente jusqu'à ce que le premier thread est terminé, à ce moment là le deuxième thread va être autorisé à rentrer dans la méthode add, et va à son tour la bloquer pour son usage unique.
Comme il n'y a plus de conflit, les deux threads manipuleront toujours les bonnes valeurs de "n" et on aura bien un affichage jusqu'à n=200.
Prenons un exemple : tu as deux threads qui font la même chose en même temps.
Ils lisent la valeur de "n", lui ajoute 1, et stocke le résultat dans "m".
Puis ils attendent un petit peu (pour simuler une charge de travail)
Enfin, ils mettent à jour "n" avec la valeur de "m", et affiche la nouvelle valeur.
Les deux Threads recommencent chacun cette opération 100 fois.
public class Test { public static Integer n=0; static class Ajout extends Thread { private static void add() { int m = n + 1; try { Thread.sleep(0,1); } catch (InterruptedException e) { } n = m; System.out.println(n); } @Override public void run() { for (int i=0; i<100; i++) add(); } } public static void main(String[] args) { Ajout a1 = new Ajout(); Ajout a2 = new Ajout(); a1.start(); a2.start(); } }
Le résultat attendu pour ce calcul est donc de voir s'afficher 1, 2, 3, 4... 199, et 200.
Or ce n'est pas cela qu'on obtient !
En effet, les deux threads s'exécutent en parallèle, mais ils se partagent la même variable de n, il peut donc y avoir des conflits.
Exemple : le premier thread lit "n=12" ce qui donne "m=13". Mais en même temps, le deuxième thread lit lui aussi "n=12" ce qui donne aussi "m=13". Ils vont donc tous les deux mettre à jour "n" avec la valeur 13, alors que l'on aurait voulu avoir 14.
Comment résoudre le problème ?
Tout simplement en ajoutant le mot clé "synchronized" à la méthode add, cela va restreindre l'accès à la méthode à un seul thread à la fois. Si un thread est en train d'exécuter la méthode add, le deuxième thread qui va vouloir y rentrer va être mis en attente jusqu'à ce que le premier thread est terminé, à ce moment là le deuxième thread va être autorisé à rentrer dans la méthode add, et va à son tour la bloquer pour son usage unique.
Comme il n'y a plus de conflit, les deux threads manipuleront toujours les bonnes valeurs de "n" et on aura bien un affichage jusqu'à n=200.
Merci.
Le mot clé static n'a aucun rapport avec l'utilisation des threads ou la synchronisation, il sert juste à indiquer qu'il s'agit d'objet (ex: n), de méthode (ex: add), ou de classe (ex: Ajout) qui s'utilisent indépendamment de tout objet.
Alors effectivement ça va parfois ensemble, mais ce n'est pas systématique !
Voici un exemple, qui fait à peu près la même chose, mais sans utiliser le mot-clé static :