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

Langage Java Discussion :

Problème ReentrantReadWriteLock: IllegalMonitorStateException


Sujet :

Langage Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut Problème ReentrantReadWriteLock: IllegalMonitorStateException
    Bonjour,

    J'ai un problème lié à l'usage des ReentrantReadWriteLock. Pourriez-vous m'aider?

    Voici mon problème : voulant protéger l'accès multi-thread à un objet en écriture mais pas en lecture (pour des raisons de performances), j'ai utilisé les ReentrantReadWriteLock de Java. J'ai utilisé une implémentation quasi identique à celle de la doc :

    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 Map<String,String> getTranslationDictionary(String language){
            readLock.lock();
            try{
                if (translationCache==null) {
                    readLock.unlock();
                    writeLock.lock();
                    if (translationCache==null) reloadCache();
                    readLock.lock();
                    writeLock.unlock();
                }
                return translationCache.get(language);
            } finally {
                readLock.unlock();
            }
        }
    Lorsque je lance mon application, j'attrape a chaque cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    java.lang.IllegalMonitorStateException
        at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(ReentrantReadWriteLock.java:275)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1215)
        at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.unlock(ReentrantReadWriteLock.java:576)
        at be.approach.brooklyn.logic.impl.ResourceBundleLogicImpl.getTranslationDictionary(ResourceBundleLogicImpl.java:69)
    Auriez-vous une idée de ce qui ne tourne pas rond?

    Merci d'avance pour votre aide!

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,



    Je pense qu'il y a une exception qui vient semer la pagaille. Dans la doc le code donné ne gère pas les exceptions : (exception handling is elided for simplicity)


    En fait je suppose que reloadCache() doit remonter une exception, ce qui fait que tout le traitement qui suit n'est pas exécuté... on passe directement dans le finally pour "libérer" le readLock alors qu'on ne l'a pas locké (on est dans le writeLock), ce qui remonte une IllegalMonitorStateException qui "cache" la première exception...

    C'est le danger des blocs finally : si une exception y survient cela peut en cacher une autre


    Perso j'utiliserais deux try/finally :
    1. Le premier pour libérer le readLock (comme tu le fais déjà).
    2. Le second pour restaurer le readLock après l'utilisation du writeLock, et fermé ce dernier.



    Ce qui donnerait :
    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
    	public Map<String,String> getTranslationDictionary(String language) {
    		// On pose le lock de lecture
    		readLock.lock();
    		try {
    			if (translationCache == null) {
    				// On libère le lock de lecture
    				// Pour attendre le lock en écriture
    				readLock.unlock();
    				writeLock.lock();
    				try {
    					// On effectue le code avec le lock d'écriture
    					if (translationCache == null)
    						reloadCache();
    				} finally {
    					// On reprend le lock en lecture
    					// Puis on libère le lock en écriture
    					readLock.lock();
    					writeLock.unlock();
    				}
    			}
    			return translationCache.get(language);
    		} finally {
    			// On libère le lock de lecture
    			readLock.unlock();
    		}
    	}


    A noter qu'on pourrait reprendre le lock en lecture juste après avoir obtenu celui en écriture :
    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
    	public Map<String,String> getTranslationDictionary(String language) {
    		// On pose le lock de lecture
    		readLock.lock();
    		try {
    			if (translationCache == null) {
    				// On libère le lock de lecture
    				// Pour attendre le lock en écriture
    				// Et reprendre le lock en lecture
    				readLock.unlock();
    				writeLock.lock();
    				readLock.lock();
    				try {
    					// On effectue le code avec le lock d'écriture
    					if (translationCache == null)
    						reloadCache();
    				} finally {
    					// Puis on libère le lock en écriture
    					writeLock.unlock();
    				}
    			}
    			return translationCache.get(language);
    		} finally {
    			// On libère le lock de lecture
    			readLock.unlock();
    		}
    	}

    a++

    a++

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut
    Ok, super, tu as tout à fait raison, ma méthode générait une exception.
    Je n'avais pas pensé que l'exception du finally masquerait l'exception dans ma méthode! Je vais au moins rajouter un printStackTrace dans un bloc catch.

    Pour le readlock par contre ce n'est pas nécessaire de le reprendre juste après celui en écriture : le write lock est bloquant pour les read lock aussi. C'est un des avantages de cette technique.

    Mais merci beaucoup, tu viens de me débloquer!

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Asterius Voir le message
    Pour le readlock par contre ce n'est pas nécessaire de le reprendre juste après celui en écriture : le write lock est bloquant pour les read lock aussi. C'est un des avantages de cette technique.
    Oui je sais, mais de toute manière tu dois reprendre le readLock donc autant le faire le plus tôt possible pour ne pas se retrouver dans un cas où on ne le récupèrerais pas

    a++

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

Discussions similaires

  1. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18
  2. Problème d'impression
    Par IngBen dans le forum C++Builder
    Réponses: 7
    Dernier message: 22/05/2002, 11h37
  3. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10
  4. Réponses: 6
    Dernier message: 25/03/2002, 21h11

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