[java] synchronized
karine
-
jmarc -
jmarc -
Bonjour,
j'ai une méthode, et j'ai des threads clients qui executent cette methode.
Je voudrais qu'il n'y ait qu'un seul client à la fois qui execute cette methode.
J'ai essayé avec synchronized, mais ça n'a pas l'air de marcher. Je vous passe le code :
Moi je voudrai avoir à l'affichege tmp + referer + ID de chaque client, dans cet ordre.
Mais j'ai des trucs du genre
Referer
Referer
ID
ID
ID
ID
Malgré le synchronized, tout est imbriqué.
Comment je peux faire ?
Merci
j'ai une méthode, et j'ai des threads clients qui executent cette methode.
Je voudrais qu'il n'y ait qu'un seul client à la fois qui execute cette methode.
J'ai essayé avec synchronized, mais ça n'a pas l'air de marcher. Je vous passe le code :
public synchronized traitement() {
System.out.println(tmp);
System.out.println(referer);
System.out.println(ID);
}
Moi je voudrai avoir à l'affichege tmp + referer + ID de chaque client, dans cet ordre.
Mais j'ai des trucs du genre
Referer
Referer
ID
ID
ID
ID
Malgré le synchronized, tout est imbriqué.
Comment je peux faire ?
Merci
A voir également:
- [java] synchronized
- Jeux java itel - Télécharger - Jeux vidéo
- Waptrick java football - Télécharger - Jeux vidéo
- Waptrick java voiture - Télécharger - Jeux vidéo
- Java apk - Télécharger - Langages
- Eclipse java - Télécharger - Langages
6 réponses
avec synchronized la méthode ne peut être appelée qu'une seul fois en même temps.
Mais tu dois avoir plusieurs instantces du même objet.
il faut faire un singleton.
public class Traitement{
// variable d'instance
private static Traitement instance;
//constructeur privé
private Traitement(){}
//récupération de l'instance
public static synchronized Traitement getInstance() {
if (instance == null) {
instance = new Traitement();
}
return instance;
}
public static synchronized traitement() {
System.out.println(tmp);
System.out.println(referer);
System.out.println(ID);
}
}
tu appelles ta méthode en static par
Traitement.traitement()
Mais tu dois avoir plusieurs instantces du même objet.
il faut faire un singleton.
public class Traitement{
// variable d'instance
private static Traitement instance;
//constructeur privé
private Traitement(){}
//récupération de l'instance
public static synchronized Traitement getInstance() {
if (instance == null) {
instance = new Traitement();
}
return instance;
}
public static synchronized traitement() {
System.out.println(tmp);
System.out.println(referer);
System.out.println(ID);
}
}
tu appelles ta méthode en static par
Traitement.traitement()
Au dernière nouvelle, la meilleure façon de faire un bon singleton en Java, c'est de faire un "Double Checked Singleton" en utilisant volative.
// La classe est final, car un singleton n'est pas sensé avoir d'héritier,
// En effet, en Java il n'y a pas de polymorphisme sur les méthodes static, il est
// donc préférable de verrouiller la classe eto.
public final class Singleton {
private static volatile Singleton instance = null;
// D'autres attributs, classiques et non static
private String xxx;
private int zzz;
/**
* Constructeur de l'objet.
*/
private Singleton() {
// La présence d'un constructeur privé supprime
// le constructeur public par défaut.
// Qui plus est seul le singleton peut s'instancier lui même
super();
}
/**
* Donne l'instance courante du singleton.
* @return Retourne l'instance du singleton.
*/
public final static Singleton getInstance() {
//Le "Double Check Singleton"/"Singleton doublement vérifié" permet d'éviter un appel coûteux à synchronized,
//une fois que l'instanciation est faite.
if (Singleton.instance == null) {
// Le mot-clé synchronized sur ce bloc empêche
// toute instanciation multiple même par différents threads.
// Il est TRES important.
synchronized(this) {
if (Singleton.instance == null) {
Singleton.instance = new Singleton();
}
}
}
return Singleton.instance;
}
// D'autres méthodes classiques et non static
public void faireXxx(...) {
...
this.xxx = "bonjour";
}
public void faireZzz(...) {
...
}
}
Cf. http://fr.wikipedia.org/wiki/Singleton_(patron_de_conception)#Java
Cf. http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
// La classe est final, car un singleton n'est pas sensé avoir d'héritier,
// En effet, en Java il n'y a pas de polymorphisme sur les méthodes static, il est
// donc préférable de verrouiller la classe eto.
public final class Singleton {
private static volatile Singleton instance = null;
// D'autres attributs, classiques et non static
private String xxx;
private int zzz;
/**
* Constructeur de l'objet.
*/
private Singleton() {
// La présence d'un constructeur privé supprime
// le constructeur public par défaut.
// Qui plus est seul le singleton peut s'instancier lui même
super();
}
/**
* Donne l'instance courante du singleton.
* @return Retourne l'instance du singleton.
*/
public final static Singleton getInstance() {
//Le "Double Check Singleton"/"Singleton doublement vérifié" permet d'éviter un appel coûteux à synchronized,
//une fois que l'instanciation est faite.
if (Singleton.instance == null) {
// Le mot-clé synchronized sur ce bloc empêche
// toute instanciation multiple même par différents threads.
// Il est TRES important.
synchronized(this) {
if (Singleton.instance == null) {
Singleton.instance = new Singleton();
}
}
}
return Singleton.instance;
}
// D'autres méthodes classiques et non static
public void faireXxx(...) {
...
this.xxx = "bonjour";
}
public void faireZzz(...) {
...
}
}
Cf. http://fr.wikipedia.org/wiki/Singleton_(patron_de_conception)#Java
Cf. http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
essais ta méthode e remplaçant System.out.println() par System.err.println() l'IO System.out est asynchrone alors que la System.err est synchrone
C'est pas beau comme solution mais si tu fais un truc du style
public synchronized traitement() {
System.out.println(tmp + "\n" + referer + "\n" + ID);
}
Ca te fais toujours pareil ?
public synchronized traitement() {
System.out.println(tmp + "\n" + referer + "\n" + ID);
}
Ca te fais toujours pareil ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
En fait j'ai mis des affichages pour pas vous embrouiller la tête.
Mais il faut imaginer qu'à la place des System.out.println, j'ai des requêtes sur une BD, et les threads font n'importe quoi !
Comment je peux faire, synchronized ne fonctionne pas.
Comment faire pour qu'une méthode ne soit appelée que par un thread à la fois ?
merci beaucoup!!
Mais il faut imaginer qu'à la place des System.out.println, j'ai des requêtes sur une BD, et les threads font n'importe quoi !
Comment je peux faire, synchronized ne fonctionne pas.
Comment faire pour qu'une méthode ne soit appelée que par un thread à la fois ?
merci beaucoup!!
Rebonjour !
j'ai une petite question, est-ce que oui ou non synchronized mis devant un nom de méthode empêche deux threads de faire cette méthode en même temps ?
Parce que j'ai un compteur qui est incrémenté dans cette méthode et les threads l'incrémentent en même temps, ce qui est assez énervant !! :-)
J'ai pourtant mis synchronized.
J'ai aussi essayé avec des semaphores, pas beaucoup plus de succès.
aidez-moi s'il vous plait !!
merci
j'ai une petite question, est-ce que oui ou non synchronized mis devant un nom de méthode empêche deux threads de faire cette méthode en même temps ?
Parce que j'ai un compteur qui est incrémenté dans cette méthode et les threads l'incrémentent en même temps, ce qui est assez énervant !! :-)
J'ai pourtant mis synchronized.
J'ai aussi essayé avec des semaphores, pas beaucoup plus de succès.
aidez-moi s'il vous plait !!
merci
le mot clef synchronized sur les méthodes d'une classe empeche l'execution simultanée des ces methodes sur une instance precise de la classe par 2 (ou plus) threads différents.
En gros si:
class classA
{
int iCnt = 0;
public synchronized void incrementValeur(){ iCnt++; }
public synchronized void decrementValeur() {iCnt--; }
}
et 2 instances A & B de la classA, il sera possible d'appeler par 2 thread différent et simulatéement incrementValeur et/ou decrementerValeur sur chacune de ces instances, Mais il ne sera pas possible d'executer par 2 thread différents un appel à incrementValeur sur la meme instance de classA.
En gros si:
class classA
{
int iCnt = 0;
public synchronized void incrementValeur(){ iCnt++; }
public synchronized void decrementValeur() {iCnt--; }
}
et 2 instances A & B de la classA, il sera possible d'appeler par 2 thread différent et simulatéement incrementValeur et/ou decrementerValeur sur chacune de ces instances, Mais il ne sera pas possible d'executer par 2 thread différents un appel à incrementValeur sur la meme instance de classA.