java.lang.IllegalMonitorStateException: l'objet n'est pas verrouillé par le thread avant de wait()?
Je suis en utilisant la boîte de dialogue de progression.j'ai besoin d'arrêter le thread lorsque l'utilisateur ferme la progressdialog .malheureusement, celui-ci donnant exception pls m'aider..
De l'intérieur de la classe
class UpdateThread extends Thread{
public void run() {
while (true){
count=adapter.getCount();
try {
mHandler.post( new Runnable() {
public void run() {
Log.i(TAG,count+"count");
progressDialog.setMessage(count + "Device found");
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Oncreate
updateThread=new UpdateThread();
progressDialog= new ProgressDialog(GroupListActivity.this);
synchronized (this) {
updateThread.start();
}
ondismissal
progressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
try {
synchronized (this) {
updateThread.wait(300);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG,"Thread is stopped");
}
});
- Exactement ce que vous essayez d'atteindre avec les serrures?
- sa présentation exception.donc je lock
- Je comprends que vous avez à utiliser synchronisé si vous appelez
wait
, mais je n'ai pas (a) pourquoi vous êtes aussi de la synchronisation sur l'appel deupdateThread.start
, ou (b) pourquoi vous utilisezwait
pour commencer (puisque vous ne l'utilisez pasnotify
ounotifyAll
). Je soupçonne que vous êtes à la synchronisation et à l'aide dewait
où vous ne devriez pas l'être. - Ajout d'une réponse que les modifications de votre code pour accomplir ce qu'il semble que vous essayez de faire.
Vous devez vous connecter pour publier un commentaire.
C'est faux:
Le problème est, ce qu'il va se réveiller ce fil? C'est-à-dire, comment avez-vous garantie que l'autre thread ne vais pas l'appeler
foo.notify()
avant le premier thread appellefoo.wait()
? C'est important parce que l'objet foo ne veut pas se souvenir qu'il a été averti si l'informer d'appel qui se produit en premier. Si il n'y a qu'un notify(), et si cela se produit avant que le wait(), puis le wait() ne retournera jamais.Voici comment attendre et informer étaient destinés à être utilisés:
Choses les plus importantes à noter dans cet exemple, qu'il y a un test explicite de la condition (c, q.peek() != null), et que personne ne change la condition sans verrouillage de la serrure.
Si le consommateur est appelé en premier, puis il va trouver de la file d'attente vide, et il va attendre. Il n'y a pas d'instant où le producteur peut se glisser dans, ajouter un Produit à la file d'attente, et d'en notifier le verrou jusqu'à ce que le consommateur est prêt à recevoir la notification.
D'autre part, si le producteur est appelé en premier, puis le consommateur est garanti de ne pas appeler wait().
La boucle de la consommation est importante pour deux raisons: la première est que, si il n'y a plus d'un thread consommateur, alors il est possible pour un consommateur de recevoir une notification, mais alors un autre consommateur se faufile et vole le Produit de la file d'attente. La seule chose raisonnable pour la première consommateurs à faire dans ce cas est d'attendre encore pour le prochain Produit. L'autre raison que la boucle est important, c'est que la Javadoc dit Objet.wait() est autorisé à revenir même quand l'objet n'a pas été notifié. Que l'on appelle une "fausse réveil", et la bonne façon de le gérer est de revenir en arrière et attendre de nouveau.
A noter également: La serrure est
private
et la file d'attente estprivate
. Qui garantit qu'aucune autre unité de compilation va interférer avec la synchronisation dans cette unité de compilation.Et remarque: La serrure est un autre objet à partir de la file d'attente. Qui garantit que la synchronisation dans cette unité de compilation ne sera pas interférer avec ce que la synchronisation que la File d'attente de la mise en œuvre (le cas échéant).
NOTE: Mon exemple de ré-invente la roue à prouver un point. Dans le code réel, vous pouvez utiliser le put() et de prendre() les méthodes d'un ArrayBlockingQueue qui prendrait soin de l'ensemble de l'attente et de la notification pour vous.
o.wait()
libère le thread appelant verrou suro
, alors qu'il attend une notification, puis il acquiert à nouveau le verrou avant il retourne.Vous ne pouvez attendre sur un objet si vous détenez déjà un verrou sur elle, vous pourriez essayer:
... mais je ne suis pas vraiment sûr de ce que vous essayez d'atteindre avec les serrures.
On dirait vraiment que vous essayez d'utiliser
synchronized
etwait
où vous ne devriez pas l'être.Si vous voulez vraiment attendre le thread de finition, vous devriez être en train de faire quelque chose comme ceci
Dans votre
UpdateThread
:Dans votre création:
Dans votre apaisement:
Remarque, j'ai ajouté une condition de sortie de votre fil de sorte qu'il arrête réellement (comme c'est, votre fils va continuer). Vous voudrez probablement faire de la sortie de la condition privée et d'ajouter une définition pour la propreté. Aussi, je suis en utilisant
join
de bien attendre que votre thread terminer.