java.lang.IllegalMonitorStateException: (m=null) n'a pas réussi à obtenir moniteur pour
Pourquoi cela se produit? Le truc, c'est que le moniteur de l'objet n'est pas nulle, mais encore nous obtenir cette exception assez souvent:
java.lang.IllegalMonitorStateException: (m=null) Failed to get monitor for (tIdx=60)
at java.lang.Object.wait(Object.java:474)
at ...
Le code qui la provoque, c'est une simple piscine solution:
public Object takeObject() {
Object obj = internalTakeObject();
while (obj == null) {
try {
available.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
obj = internalTakeObject();
}
return obj;
}
private Object internalTakeObject() {
Object obj = null;
synchronized (available) {
if (available.size() > 0) {
obj = available.keySet().iterator().next();
available.remove(obj);
synchronized (taken) {
taken.put(obj, Boolean.valueOf(true));
}
}
}
return obj;
}
public void returnObject(Object obj) {
synchronized (taken) {
taken.remove(obj);
}
synchronized (available) {
if (available.size() < size) {
available.put(obj, Boolean.valueOf(true));
available.notify();
}
}
}
Suis-je raté quelque chose?
MODIFIER: L'exception se produit dans available.wait();
ligne.
- pouvez-vous nous dire quelle est la ligne 474 dans le code source?
- l'exception se produit dans disponible.wait(); ligne, mais la ligne 474 est de java.lang.La classe d'objet.
Vous devez vous connecter pour publier un commentaire.
Voir la javadoc de l'Objet.attendre.
en particulier "Le thread courant doit être propriétaire de cet objet à l'écran." et "[jette] IllegalMonitorStateException - si le thread actuel n'est pas le propriétaire de l'objet du moniteur". Qui est, vous avez besoin de synchroniser sur l'objet que vous allez à l'appel en attente sur.
de sorte que votre code devrait être:
available.notify()
.this.wait()
devrait fonctionner. Ce exactement avez-vous le faire?this.wait()
, mais ceux propre le moniteur de l'objet dans lequel ces méthodes sont en cours d'exécution, pasavailable
. Ce n'est donc pas le même quesynchronized(available)
available.wait();
doivent être synchronisés(disponible) sectiontakeObject() la méthode doit être synchronisé ou de, nous devons l'écrire synchronisé bloc à l'intérieur de cette méthode. J'espère que u doit obtenir le temps de compilation d'exception pour cette.
Vous obtenez le "IllegalMonitorStateException" de
parce que le thread qui appelle le wait() la méthode n'est pas le propriétaire de l'Objet du moniteur qui est
référencé par le "disponible" la référence d'objet.
Pour un thread pour devenir le propriétaire d'un objet à l'écran, il y a 3 façons.
Simple exemple de code pour chaque scénario. Tous les trois extraits de code sont des classes séparées pour chaque type, il suffit de copier le code et l'exécuter. J'ai ajouté des commentaires lourdement dans le code pour expliquer ce qui se passe dans chaque cas. Si c'est trop de commentaires pour vous. il suffit de supprimer pour rendre le code plus concis.
Aussi, lire le code de la méthode main() de la première à se faire une idée sur threadOne et threadTwo premier.
Par l'exécution d'un synchronisé méthode d'instance de cet objet.
En exécutant le corps d'un bloc synchronisé qui se synchronise sur l'objet.
Pour les objets de type Classe par l'exécution d'un synchronisé méthode statique de la classe.