IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

synchronized ne marche pas


Sujet :

avec Java

  1. #1
    Membre régulier Avatar de 0redd
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 141
    Points : 79
    Points
    79
    Par défaut synchronized ne marche pas
    Bonsoir
    j'ai commencé c'est derniers jour a apprendre les threads dans java, et j'ai fait un petit exemple pour mieux comprendre synchronized, mais hélas ce dernier ne marche pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    class CompteBancaire {
     
            private int balance = 50;
     
    	public int getSolde() {
    		return balance;
    	}
    	public void retrait(int montant) {
    		balance = balance - montant;
    	}
    }
     
    class Tirez implements Runnable{
     
    	private CompteBancaire account;
     
    	Tirez(Account a)
    	{
    		account = a;
    	}
     
    	private synchronized void Retrait(int montant)
    	{
    		if(account.getSolde() >= montant) 
    		{	
    			System.out.println(Thread.currentThread().getName() + " a verifié qu'il y'a du solde dans le compte");
     
    			try {
    				Thread.sleep(500);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
     
    			account.retrait(montant);
     
    			System.out.println(Thread.currentThread().getName() + " a tiré la somme de " + montant);
    			System.out.println("Le compte contient " + account.getSolde());
    		}
    		else
    			System.out.println(Thread.currentThread().getName() + " Le compte ne contient pas assez ");
    	}
     
    	public void run()
    	{
    		for(int i=0; i<5 ;i++) {
    			this.Retrait(10);
    		}	
    	}
    }
     
    //La méhode Main
     
    public class a {
    	public static void main(String[] arg) {
     
    		Account monCompte = new Account();
     
    		Tirez tirez1 = new Tirez(monCompte);
    		Tirez tirez2 = new Tirez(monCompte);
     
    		Thread t1 = new Thread(tirez1,"reda");
    		Thread t2 = new Thread(tirez2,"elle");
     
    		t1.start();
    		t2.start();
     
    	}
    }
    lorsque j'execute le code, la méthode Retrait de Tirez n'est pas atomique malgré que j'ai ajouté le mot clé synchronized devant la méthode, elle ne s'execute pas comme une seul instruction, d'ou peut venir le problème?
    Merci d'avance

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    je crois que tu confond plusieurs notions

    synchronized ne rend pas une méthode atomique, elle peux toujours n'etre que partiellement exécutée puis mise en pause. Par contre, tu a la garantie que, "pour une instance donnée", un seul Thread pourra exécuter à la fois la méthode.


    Dans ton exemple, tu as deux instances de tirez, une pour chaque Thread, ce qui, inévitablement, fait que les Thread ne se bloqueront pas mutuellement, chacun travaillant et faisant le synchronized sur une instance différente.

    Pour voir la différence, fait plutot ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class a {
    	public static void main(String[] arg) {
     
    		Account monCompte = new Account();
     
    		Tirez tirez = new Tirez(monCompte);
     
    		Thread t1 = new Thread(tirez,"reda");
    		Thread t2 = new Thread(tirez,"elle");
     
    		t1.start();
    		t2.start();
     
    	}
    }

  3. #3
    Membre régulier Avatar de 0redd
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 141
    Points : 79
    Points
    79
    Par défaut
    merci pour votre réponse, j'ai compris l'erreur que j'avais fait en déclarant 2 instances de Tirez, donc j'avais 2 comptes,
    Mais sinon dans l'affichage avec synchronized je trouve toujours par exemple :
    Elle Verifie ;
    Elle tire de l'argent,

    sans synchronized on trouve parfois :
    reda verifie
    Elle Verifie ;
    Elle tire de l'argent

    donc c'est pour celà que j'ai dit que c'était atomique,
    le fait de verifié tiré l'argent par une personne ne l'est pas?

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    atomique, ça veux dire tout ou rien, et pas possible d'interrompre. Une opération atomique n'a justement pas besoin d'être synchronisée car elle ne peux pas se corrompre suite à une interruption et un changement de valeur pendant celle-ci

    Les variables atomiques en java sont ici:
    http://java.sun.com/j2se/1.5.0/docs/...e-summary.html

  5. #5
    Membre régulier Avatar de 0redd
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 141
    Points : 79
    Points
    79
    Par défaut
    C'est que je me suis a nouveau perdu,

    vous aviez dit:

    synchronized peux toujours n'etre que partiellement exécutée puis mise en pause. Par contre, tu a la garantie que, "pour une instance donnée", un seul Thread pourra exécuter à la fois la méthode.

    Immaginons celà:

    Thread 1: Verifie qu'on a de l'argent dans le compte;
    Puis le Thread1 est mis en pause ( normal c'est pas atomique , ça j'ai compris )
    jusque là, y'a un seul thread qui execute la méthode;

    Arrive le Thread2: Verifie qu'on a de l'argent dans le compte;
    ...
    et toujours y'a qu'un seul thread qui est executé à la fois,

    or j'avais fais synchronized pour évité cette situation.

    je sait que c'est pas ça ce qui se passe quand je fais synchronized, mais que ce passe t'il??

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Salut !

    Arrive le Thread2: Verifie qu'on a de l'argent dans le compte;
    Non puisque le thread2 ne rentrera pas dans la méthode synchronisée tant que thread1 n'en sera pas sorti.
    Elle est la la synchronisation.
    Je vais détailler un peu le fonctionnement :

    Un thread qui entre dans une méthode synchronisée d'un objet place un verrou sur cet objet. Le verrou est libéré lorsque le thread sort de la méthode synchronisée.
    Si ce même thread se met en pause (de lui même ou par ordre de l'uc) avant d'être sorti de la méthode synchronisée, il conserve le verrou.
    Ainsi, si un autre thread souhaite entrer dans une méthode synchronisée de ce même objet, il ne pourra pas le faire tant que le 1er thread n'aura pas lâché le verrou de l'objet.

    Appliqué à ton exemple, ca donnerait :

    Thread 1: Verifie qu'on a de l'argent dans le compte et place un verrou sur l'objet CompteBancaire
    ...
    Thread1 est mis en pause
    ...
    Arrive le Thread2 qui veut rentrer dans la méthode 'Retrait' mais qui ne peut pas puisque l'objet CompteBancaire est verouillé pour les méthodes synchronisées.
    ...
    Thread1 se re-exécute : il sort de la méthode 'Retrait'
    ...
    Thread2 se re-exécute : il n'y a plus de verrou sur CompteBancaire , il peut maintenant rentrer dans la méthode 'Retrait'

    En résumé, thread2 ne fera la vérification sur le compte (entrer dans la méthode synchronisée) qu'une fois qu'il sera sûr que thread1 ne peut plus modifier l'état de compte.
    Sans ce mécanisme de verrou, la vérification de thread2 ne serait plus fiable puisque thread1 pourrait modifier l'état du compte si thread2 se fait interrompre.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Petite suggestion :
    Si tu veux voir la différence avec et sans synchronisation,il suffit de regarder les soldes.
    Sans synchronisation, tu pourras obtenir parfois des soldes négatifs , ce que tu n'auras pas avec la version synchronisée.

    Sinon
    donc c'est pour celà que j'ai dit que c'était atomique,
    le fait de verifié tiré l'argent par une personne ne l'est pas?
    Effectivement ca se dit, même si cette vision contredit un peu la définition d'origine de l'atomicité.
    C'est pas l'exécution du thread qui est atomique mais l'état des données traitées par la méthode synchronisée.

  8. #8
    Membre régulier Avatar de 0redd
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 141
    Points : 79
    Points
    79
    Par défaut
    Voilà j'ai compris le tous, merci beaucoup pour votre aide , je ne savais pas qu'il y'avait un système de verrous, et pensée que la méthode ne pouvais pas être interrompus, mais là c'est clair.
    Encors une fois merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. 'SHOW TABLES' marche pas sous postgresql !?
    Par fet dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 13/05/2004, 09h28
  2. Maximiser fenêtre ne marche pas
    Par sandrinec dans le forum Composants VCL
    Réponses: 2
    Dernier message: 12/06/2003, 12h02
  3. Réponses: 9
    Dernier message: 07/05/2003, 12h57
  4. [GifDecoder] marche pas dans applet avec IE
    Par formentor dans le forum Applets
    Réponses: 2
    Dernier message: 06/05/2003, 10h43
  5. Sysdate qui marche pas ??
    Par StouffR dans le forum Langage SQL
    Réponses: 4
    Dernier message: 28/08/2002, 13h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo