Le sommeil d'un thread jusqu'à ce qu'un événement est assisté, dans un autre thread à partir d'une autre classe
J'ai une application qui tire des 2 threads, le 1er lance une autre classe pour faire une partie de la transformation qui à son tour lance un 3ème classe pour faire encore plus de traitement. Le 2ème fil dans la classe principale doit attendre jusqu'à ce qu'un événement dans la 3e classe se termine avant qu'il effectue son travail. Comment cela peut-il être atteint?
J'avais essayé de mettre en œuvre un wait/notify pour partager un verrou d'objet entre les deux fils, mais, techniquement, cela ne fonctionne pas comme je l'ai découvert à la dure. Puis-je partager un verrou entre les classes? Remarque, une instance de la 3e classe est déclarée dans la 1ère classe et transmis en tant que paramètre à la 2e classe. Aussi j'ai essayé de créer une valeur booléenne en 3e classe qui indique lorsque l'événement est terminé interroger 2ème fil jusqu'à cette valeur est true. Cela a fonctionné, mais n'est pas très souhaitable. Aussi est actionListner une meilleure approche de ce problème?
- Quand vous dites de 2e et 3e catégories, pensez-vous vraiment dire 2ème fil et 3ème fil?
- De 2e classe est effectué en 1ère fil, mais qui lance une troisième classe qui peut ou ne peut pas lancer d'autres threads.
Vous devez vous connecter pour publier un commentaire.
Quel problème rencontrez-vous? Comme vous le décrire, il devrait fonctionner. Par exemple, vous pourriez mettre en œuvre des 2 méthodes sur la 3ème classe qui gardent un drapeau qui est vérifiée à partir de l'un et de l'ensemble de la classe à l'aide de l'exemple serrure:
(note: tapé à partir de la mémoire, de ne pas vérifier à l'aide d'un Java compiler)
En principe, la
this.
avant de l'attendre et notifyAll n'est pas nécessaire, je trouve ça plus clair pour les inclure dans cette situation.Utiliser un CountDownLatch avec une valeur initiale de 1.
Faire de la 3e classe appel compte à rebours() une fois le traitement terminé. Le thread appelant peut ensuite appeler await(), qui permet de bloquer jusqu'à ce que le traitement est terminé.
Le problème à résoudre peut être facilement résolu en utilisant
ActionListener
ou à l'aide d'un partagéesQueue
.Choisissez-en un blocage de la file d'attente qui pourrait bloquer la consommation jusqu'à ce que quelque chose arrive dans la file d'attente. Simple, claire et éprouvée.
Si vous avez besoin de plus, regarder les projets comme http://akkasource.org/ ou http://jcp.org/en/jsr/detail?id=166 (sera inclus par défaut dans Java 7).
ActionListener
aide beaucoup avec le multi-threading. Après tout,ActionListener
est juste une interface.Vous souhaitez utiliser un comptage sémaphore. Les variables de Condition sont destinés pour l'ordonnancement des threads à l'intérieur d'un moniteur. Ce n'est pas ce que vous essayez de faire.
Vous créez un comptage sémaphore et réglez le décompte à zéro
Vous passer le sémaphore à votre classe le fait le traitement. Quand c'est fini, il augmente le nombre à 1 en appelant
s.release()
.Pour bloquer un thread jusqu'à ce que le processeur est fini, vous appelez
s.aquire()
. Cet appel sera la cause de votre autre thread pour bloquer jusqu'à ce que le processeur appelss.release()
.C'est la solution la plus simple.
Btw,
s.aquire()
ets.release()
sont thread-safe, vous n'avez pas besoin d'utiliser le synchroniser mot-clé. Les Threads peuvent partager des références à un feu et appeler ses méthodes sans verrouillage.Mise à JOUR:
Je vais répondre à votre commentaire ici au lieu de faire un nouveau commentaire.
Oui, dans votre cas, un wait()/notify() la solution est similaire à l'utilisation d'un sémaphore. À la réécriture du programme de solution avec un sémaphore, il ressemblerait à:
Il est beaucoup plus simple et vous n'avez pas besoin d'une inutile de verrouillage (avis j'ai enlevé le mot-clé synchronized à partir de la méthode de cad.).
Il y a 2 différences entre les variables de condition (wait()/notify()) et les sémaphores.
Différence #1: les appels de notify() peuvent être perdus, les appels à la release() ne sont jamais perdus
La première différence est que les appels à notify() sont perdues si il n'y a pas de fil d'attente via un appel à wait(). Le travail consiste à vérifier l'état avant l'appel à wait(). Fondamentalement, nous devons nous rappeler que notify() a été appelé avec une variable partagée, afin de ne pas accidentellement l'appel en attente() après que le travailleur appels notify(), ou bien nous l'impasse. Le comptage des sémaphores du travail, peu importe l'ordre dans lequel les acquérir() et release() sont appelées parce qu'elles maintiennent un nombre à l'intérieur.
Différence #2: les appels à wait() effectue automatiquement la libération d'un verrou, les appels à acquérir() ne sont pas
Des renseignements contextuels de l'aide ici. Dans votre programme de la
boolean done = false;
la variable est la condition, mais il n'est pas de la variable de condition. Confusion terminologique, je sais. La variable de condition est la variable qui a des opérations de wait() et notify(). Chaque objet en Java a une variable de condition cachées à l'intérieur et une serrure correspondante.
Toutes les variables de condition sont associés avec un cadenas. Vous devez acquérir le verrou avant de vous pouvez appeler wait() et notify() (vous obtiendrez une exception d'exécution si vous n'en avez pas, essayez). Une fois que le verrou est acquis, les appels à wait() automatiquement libérer le verrou, permettant à un autre fil à l'intérieur du moniteur pour peut-être appeler notify(). Parfois, c'est exactement ce que vous voulez, et en essayant de simuler ce comportement avec les sémaphores sera beaucoup plus compliqué.
Note: je suis en utilisant la définition académique de moniteur qui diffère totalement de la Java définition d'un moniteur.
Je pense que
join()
opération s'adapter à cet effetIllustration:
Permet de dire que vous avez 2 fils
thead1 -> Le thread qui doit attendre.
thread2 -> Le thread sur lequel thread1 a plus qu'à attendre.
puis dans le code de thread1, à l'endroit où vous souhaitez attendre, écrire
Espérons que cette aide!