Comment utiliser les attendre et de les informer en Java sans IllegalMonitorStateException?
J'ai 2 matrices et j'ai besoin de les multiplier et de les imprimer ensuite les résultats de chaque cellule. Dès qu'une cellule est prête j'ai besoin de l'imprimer, mais par exemple j'ai besoin d'imprimer le [0][0] cellule avant de la cellule [2][0] même si le résultat de [2][0] est prêt le premier. J'ai donc besoin d'imprimer en ordre.
Donc, mon idée est de faire de l'imprimante de l'attente du thread jusqu'à ce que le multiplyThread
informe que la bonne cellule est prêt à être imprimé, puis le printerThread
impression sera de la cellule et de revenir à l'attente et ainsi de suite..
J'ai donc ce thread qui effectue la multiplication:
public void run()
{
int countNumOfActions = 0; //How many multiplications have we done
int maxActions = randomize(); //Maximum number of actions allowed
for (int i = 0; i < size; i++)
{
result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
countNumOfActions++;
//Reached the number of allowed actions
if (countNumOfActions >= maxActions)
{
countNumOfActions = 0;
maxActions = randomize();
yield();
}
}
isFinished[rowNum][colNum] = true;
notify();
}
Thread qui imprime le résultat de chaque cellule:
public void run()
{
int j = 0; //Columns counter
int i = 0; //Rows counter
System.out.println("The result matrix of the multiplication is:");
while (i < creator.getmThreads().length)
{
synchronized (this)
{
try
{
this.wait();
}
catch (InterruptedException e1)
{
}
}
if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
{
if (j < creator.getmThreads()[i].length)
{
System.out.print(creator.getResult()[i][j] + " ");
j++;
}
else
{
System.out.println();
j = 0;
i++;
System.out.print(creator.getResult()[i][j] + " ");
}
}
}
Maintenant, il me jette ces exceptions:
Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
ligne 49 dans multiplyThread
est le "notify()"..je pense que j'ai besoin d'utiliser la synchronisation différemment, mais je ne suis pas sûr de savoir comment.
Si quelqu'un peut aider ce code fonctionne, je l'apprécie vraiment.
Vous devez vous connecter pour publier un commentaire.
Pour être en mesure d'appeler notify() vous avez besoin de synchroniser sur le même objet.
while(!JobCompleted);
option est généralement une mauvaise idée, car elle bloque le CPU à 100% vérification de la même variable constante (voir ici)while(!JobCompleted) Thread.sleep(5);
n'a pas ce problèmewait
chaque fois que le thread courant a un verrou sur l'objet sur lequelwait
est appelé. Si vous utilisez unsynchronized
bloc ou une méthode synchronisée est complètement à vous.wait
attend jusqu'à ce quenotify
ounotifyAll
a été appelée sur le même objet.Tout en utilisant le
wait
etnotify
ounotifyAll
méthodes en Java, les éléments suivants doivent être rappelés:notifyAll
au lieu denotify
si vous vous attendez à ce que plus d'un thread attente d'un verrou.attendre
etnotify
méthodes doit être appelée dans un contexte synchronisé. Voir le lien pour une explication plus détaillée.wait()
méthode dans une boucle car si plusieurs threads sont en attente d'un verrou, et l'un d'entre eux a obtenu la serrure et de réinitialiser la condition, alors les autres threads besoin de vérifier l'état après leur réveil pour voir si elles doivent attendre encore ou pouvez commencer le traitement.wait()
etnotify()
méthode; chaque objet a son propre cadenas afin de l'appelantwait()
sur l'objet A etnotify()
sur l'objet B n'a aucun sens.Avez-vous besoin d'enfiler ce tout ? Je me demandais comment grand votre de matrices, et si il n'y a aucun avantage à avoir un thread d'impression tandis que l'autre fait de la multiplication.
Il serait peut-être intéressant de mesurer ce temps avant de faire le relativement complexe filetage de travail ?
Si vous avez besoin de l'enfiler, je voudrais créer 'n' threads pour effectuer la multiplication des cellules (peut-être " n " est le nombre de cœurs disponibles pour vous), puis utilisez la ExecutorService et L'avenir mécanisme de répartition de plusieurs multiplications simultanément.
De cette façon, vous pouvez optimiser le travail sur la base du nombre de cœurs, et que vous utilisez le plus élevé niveau de Java outils de filetage (ce qui devrait rendre la vie plus facile). Écrire les résultats dans un récepteur de la matrice, et puis il suffit d'imprimer cette fois que tous vos Futures tâches accomplies.
Disons que vous avez de "boîte noire" de l'application avec une certaine classe nommée
BlackBoxClass
qui a la méthodedoSomething();
.En outre, vous avez de l'observateur ou de l'auditeur nommé
onResponse(String resp)
qui sera appelé parBlackBoxClass
après un temps inconnu.Le flux est simple:
Permet de dire que nous ne savons pas ce qui se passe avec
BlackBoxClass
et quand nous devons obtenir de réponse, mais vous ne souhaitez pas poursuivre votre code jusqu'à ce que vous obtenir une réponse ou en d'autres mots obtenironResponse
appel. Ici entre "Synchroniser helper":Maintenant, nous pouvons mettre en œuvre ce que nous voulons:
Vous pouvez uniquement appeler informer sur des objets où vous sont propriétaires de leur moniteur. Si vous besoin de quelque chose comme
notify()
doit être synchronisé ainsiJe vais droit de l'exemple simple de vous montrer la bonne façon de l'utiliser
wait
etnotify
en Java.Donc, je vais créer deux classe nommée ThreadA & ThreadB. ThreadA appellera ThreadB.
et pour la Classe ThreadB:
nous pouvons appeler notifier à reprendre l'exécution de l'attente des objets comme
reprendre ce en invoquant informer sur un autre objet de même classe
Simple d'utilisation si vous voulez savoir Comment exécuter les threads alternativement :-
Pour ce problème particulier, pourquoi ne pas stocker vos différents résultats dans des variables, puis lorsque le dernier de votre fil est traitée, vous pouvez imprimer dans le format que vous souhaitez. Ceci est particulièrement utile si vous êtes va être à l'aide de vos antécédents de travail dans d'autres projets.
Cela ressemble à une situation pour le producteur-schéma de consommation. Si vous êtes à l'aide de java 5 ou, vous pouvez envisager d'utiliser le blocage de la file d'attente(java.util.de façon concomitante.BlockingQueue) et de laisser le thread de travail de coordination pour le cadre sous-jacent/implémentation de l'api.
Voir l'exemple de
java 5:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
ou java 7 (même exemple):
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
Vous avez gardé votre bloc de code lorsque vous appelez
wait()
, en utilisant la méthodesynchronized(this)
.Mais vous n'avez pas pris les mêmes précautions lorsque vous appelez
notify()
méthode sans utiliser gardé bloc :synchronized(this)
ousynchronized(someObject)
Si vous vous référez à la documentation oracle page sur Objet classe, qui contient
wait()
,notify()
,notifyAll()
méthodes, vous pouvez voir ci-dessous la précaution dans l'ensemble de ces trois méthodesBeaucoup de choses ont été modifiées au cours des 7 dernières années et voyons dans d'autres solutions de rechange à
synchronized
ci-dessous SE questions:Pourquoi utiliser un ReentrantLock si on peut l'utiliser synchronisée(ce)?
La synchronisation vs Verrouillage
Éviter synchronisée(ce) en Java?