41 votes

Quelqu'un peut-il expliquer les moniteurs de threads et attendre?

Quelqu'un au travail juste demandé pour le raisonnement ayant pour envelopper une attente à l'intérieur d'un synchronisé.

Honnêtement je ne vois pas le raisonnement. Je comprends ce que la documentation javadoc dire--que le fil doit être le propriétaire de l'objet à l'écran, mais pourquoi? Quels problèmes est-il éviter? (Et si c'est réellement nécessaire, pourquoi ne peut-on pas attendre méthode get le moniteur lui-même?)

Je suis à la recherche d'une assez approfondie pourquoi ou peut-être une référence à un article. Je ne pouvais pas en trouver un dans un rapide google.

Oh, aussi, comment ne thread.sommeil comparer?

edit: Grand ensemble de réponses--je souhaite vraiment que je pourrais sélectionner plus d'un, car tous m'ont aidé à comprendre ce qui se passait.

14voto

Alex Miller Points 28225

Beaucoup de bonnes réponses ici déjà. Mais je veux juste mentionner ici que l'autre DOIT le FAIRE lors de l'utilisation de wait() est de le faire dans une boucle dépend de la maladie qui vous attendent dans le cas où vous êtes en voyant les réveils intempestifs, qui dans mon expérience ne se produisent.

Attendre pour un autre thread de modifier une condition de vrai et notifier:

synchronized(o) {
  while(! checkCondition()) {
    o.wait();
  }
}

Bien sûr, ces jours, je vous recommande simplement à l'aide de la nouvelle Condition de l'objet comme il est plus clair et a plus de fonctionnalités (comme permettant à plusieurs conditions, par écluse, d'être en mesure de vérifier la file d'attente de longueur, plus de flexibilité dans les horaires ou interrompre, etc).

 Lock lock = new ReentrantLock();
 Condition condition = lock.newCondition();
 lock.lock();
 try {
   while (! checkCondition()) {
     condition.await();
   }
 } finally {
   lock.unlock();
 }

}

6voto

64BitBob Points 1755

Si l'objet n'est pas propriétaire de l'objet à surveiller lors de l'appel de l'Objet.wait(), il ne sera pas en mesure d'accéder à l'objet de l'installation d'une aviser l'auditeur jusqu'à ce que le moniteur est libéré. Au lieu de cela, il sera traité comme un thread tente d'accéder à une méthode sur un objet synchronisé.

Ou pour le dire d'une autre façon, il n'y a pas de différence entre:

public void doStuffOnThisObject()

et la méthode suivante:

public void wait()

Les deux méthodes seront bloqués jusqu'à ce que l'objet moniteur est libéré. C'est une fonction en Java pour empêcher l'état d'un objet à partir de la mise à jour de plus d'un thread. Simplement, il a des conséquences inattendues sur le wait() de la méthode.

Sans doute, l'attente() la méthode n'est pas synchronisé car cela pourrait créer des situations où le Fil a plusieurs verrous sur l'objet. (Voir les Spécifications du Langage Java/Verrouillage pour plus d'info sur ce sujet). Plusieurs verrous sont un problème parce que le wait() méthode ne pourra annuler un verrouillage. Si la méthode ont été synchronisés, ce qui permettrait de garantir que seule la méthode de verrouillage serait annulé, tout en laissant un potentiel externe verrouillage annulée. Cela permettrait de créer une situation de blocage dans le code.

Pour répondre à votre question sur le Thread.sleep(), le Thread.sleep() ne garantit pas que ce que vous êtes en attente sur a été rencontré. À L'Aide De L'Objet.wait() et de l'Objet.notify() permet à un programmeur de mettre en œuvre manuellement le blocage. Le fils va débloquer une fois qu'une notification est envoyée qu'une condition a été remplie. par exemple, Une lecture à partir du disque est terminée et les données peuvent être traitées par le thread. Fil de discussion.sleep (), il faudrait programmeur pour interroger si la condition a été remplie, puis tomber sur le dos pour dormir si elle n'a pas.

5voto

Lou Franco Points 48823

Attendez donne le moniteur, vous devez avoir à l'abandonner. Aviser doit avoir le moniteur.

La raison principale pourquoi vous voulez faire est de vous assurer que vous avez le moniteur lorsque vous revenez de wait() -- en règle générale, vous utilisez le wait/notify protocole pour la protection de certaines ressources partagées et que vous voulez qu'il soit sûr de le toucher quand attendre les retours. De même avec les aviser -- habituellement, vous sont en train de changer quelque chose et puis l'appel de notify() -- vous voulez avoir le moniteur, faire des changements, et d'appeler notify().

Si vous avez fait une fonction comme ceci:

public void synchWait() {
   syncronized { wait(); }
}

Vous n'auriez pas le moniteur lorsque vous attendez retourné -- vous pouvez l'obtenir, mais vous ne pourriez pas obtenir à côté.

5voto

Robin Points 15032

Il doit posséder le moniteur, puisque le but de l'attente() est la libération de la surveiller et de laisser les autres threads obtenir le moniteur à faire le traitement de leur propre. Le but de ces méthodes (wait/notify) est de coordonner l'accès à synchronisée blocs de code entre les deux threads que de besoin les uns des autres pour exécuter une fonction. Il n'est pas simplement une question de s'assurer que l'accès à une structure de données est thread-safe, mais pour coordonner les activités entre plusieurs threads.

Un exemple classique serait un producteur/consommateur, en cas où un thread pousse des données à une file d'attente, et un autre thread consomme les données. La consommation thread toujours besoin de la surveiller pour accéder à la file d'attente, mais la sortie du moniteur une fois la file d'attente est vide. Le producteur de fil serait alors seulement obtenir l'accès en écriture au fil lorsque le consommateur n'est plus de traitement. Il serait d'avertir le consommateur fil une fois qu'il a poussé plus de données dans la file d'attente, afin qu'elle puisse retrouver le moniteur et l'accès à la file d'attente à nouveau.

3voto

Mr Fooz Points 21092

Voici ma compréhension sur les raisons de la restriction est en fait une exigence. Je suis en se fondant sur une C++ surveiller la mise en œuvre, j'ai fait un retour tandis que, par la combinaison d'un mutex et une variable de condition.

Dans un *mutex+condition_variable=moniteur* système, l' attente d'appel définit la variable de condition dans un état d'attente et libère le mutex. La variable d'état est un état partagé, de sorte qu'il doit être verrouillé pour éviter les conditions de concurrence entre les threads qui veulent attendre et de threads qui veulent informer. Au lieu d'introduire encore un autre mutex pour verrouiller son état, le mutex est utilisé. En Java, le mutex est verrouillé correctement lorsque le sujet-à-attendre que le thread possède le moniteur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X