[synchronized]quand et pourquoi l'utiliser
Résolu
ajp55
Messages postés
482
Statut
Membre
-
ajp55 Messages postés 482 Statut Membre -
ajp55 Messages postés 482 Statut Membre -
Bonjour,
je suis nouveau dans le developpement java et j'ai vu dans certain fonction on ajoutais synchronized devant le nom de la fonction. j'ai parcouru la doc java mais je n'arrive toujours pas à comprendre ce qui peut bien me pousser à utiliser un tel mot.
quelqu'un peut-il m'expliquer quand faut -il exactement utiliser ce mot clé de java?
Merci d'avance pour vos réponses. j'en serai très ravi.
"L'ordinateur est une grande invention : il y a autant d'erreur qu'avant mais plus personne n'est responsable..."
je suis nouveau dans le developpement java et j'ai vu dans certain fonction on ajoutais synchronized devant le nom de la fonction. j'ai parcouru la doc java mais je n'arrive toujours pas à comprendre ce qui peut bien me pousser à utiliser un tel mot.
quelqu'un peut-il m'expliquer quand faut -il exactement utiliser ce mot clé de java?
Merci d'avance pour vos réponses. j'en serai très ravi.
"L'ordinateur est une grande invention : il y a autant d'erreur qu'avant mais plus personne n'est responsable..."
A voir également:
- [synchronized]quand et pourquoi l'utiliser
- Comment utiliser chromecast sur tv - Guide
- Utiliser iphone comme webcam - Guide
- Utiliser tablette comme deuxieme ecran - Guide
- Comment utiliser teamviewer - Guide
- 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 :
public class Entier { private int n; public /*synchronized*/ void inc() { n++; } public String toString() { return String.valueOf(n); } } public class Ajout extends Thread { private final int id; private final Entier ent; public Ajout(int id, Entier ent) { this.id = id; this.ent = ent; } @Override public void run() { String start = ent.toString(); for (int i=0; i<1000000; i++) ent.inc(); String end = ent.toString(); System.out.printf("Le thread %d a commencé avec n=%s et termine avec n=%s\n", id, start, end); } } public class Test { public static void main(String[] args) { Entier ent = new Entier(); for (int id=0; id<5; id++) new Ajout(id,ent).start(); } }