[java] synchronized

karine -  
 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 :

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:

6 réponses

shaiulud
 
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()
11
ggorsontanguy
 
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
3
qotsa
 
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
2
Kermitt31 Messages postés 3679 Date d'inscription   Statut Contributeur Dernière intervention   495
 
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 ?
1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
karine
 
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!!
0
Kermitt31 Messages postés 3679 Date d'inscription   Statut Contributeur Dernière intervention   495
 
Tu connais les semaphores ??? Tu utilises ce sytème ! Je ne connais pas cette solution en Java, je la connais juste en C mais elle existe forcement en Java.

Essaie de te renseigner la dessus
0
karine
 
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
0
Kermitt31 Messages postés 3679 Date d'inscription   Statut Contributeur Dernière intervention   495
 
Moi je sais pas
0
jmarc
 
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.
0