53 votes

Pourquoi wait() et notify() sont-ils déclarés dans la classe Object de Java ?

Pourquoi les wait() y notify() Les méthodes déclarées dans le Object plutôt que la classe Thread classe ?

42voto

Andrzej Doyle Points 52541

En effet, vous attendez qu'un objet donné (ou plus précisément, son moniteur) utilise cette fonctionnalité.

Je pense que vous vous trompez sur le fonctionnement de ces méthodes. Elles ne sont pas simplement au niveau de la granularité du Thread, c'est-à-dire qu'il est no un cas de simple appel wait() et être réveillé par l'appel suivant à notify() . Au contraire, vous appelez toujours wait() sur un objet spécifique, et ne sera réveillé que par des appels à notify sur cet objet .

C'est une bonne chose car, dans le cas contraire, les primitives de concurrence ne pourraient pas s'adapter ; cela reviendrait à avoir des espaces de noms globaux, puisque tout appel à notify() n'importe où dans votre programme aurait le potentiel de foutre en l'air tout code concurrent, car ils réveilleraient tous les threads bloquant sur une wait() appel. D'où la raison pour laquelle vous les appelez sur un objet spécifique ; cela donne un contexte sur lequel la paire wait-notify peut opérer, donc quand vous appelez myBlockingObject.notify() sur un objet privé, vous pouvez être sûr que vous ne réveillerez que les threads qui ont appelé les méthodes d'attente dans votre classe. Un thread Spring qui serait en train d'attendre un autre objet ne sera pas réveillé par cet appel, et vice versa.

Edit : Ou pour aborder la question d'un autre point de vue - je suppose, d'après votre question, que vous pensiez obtenir une poignée sur le fil d'attente et appeler notify() sur ce fil pour le réveiller. La raison pour laquelle ce n'est pas fait de cette façon, est que vous devriez faire beaucoup de ménage vous-même. Le thread qui va attendre devrait publier une référence à lui-même quelque part où les autres threads pourraient le voir ; cela devrait être correctement synchronisé pour assurer la cohérence et la visibilité. Et lorsque vous voulez réveiller un thread, vous devez vous emparer de cette référence, le réveiller et la supprimer de l'endroit où vous l'avez lue. Il y a beaucoup plus d'échafaudage manuel impliqué, et beaucoup plus de chance de se tromper (surtout dans un environnement concurrent) comparé à un simple appel à myObj.wait() dans le fil conducteur et ensuite myObj.notify() dans le fil de discussion sur le Waker.

10voto

valli Points 1789

La raison la plus simple et la plus évidente est que tout objet (pas seulement un fil) peut être le moniteur d'un thread. Les fonctions wait et notify sont appelées sur le moniteur. Le thread en cours d'exécution vérifie avec le moniteur. Les méthodes wait et notify sont donc dans Object et non dans Thread.

8voto

Taylor Leese Points 18895

Parce qu'un seul thread à la fois peut posséder le moniteur d'un objet et ce moniteur est ce sur quoi les threads attendent ou notifient. Si vous lisez le javadoc para Object.notify() y Object.wait() il est décrit en détail.

1voto

Le mécanisme de synchronisation implique un concept - le moniteur d'un objet. Lorsque wait() est appelé, le moniteur est demandé et la poursuite de l'exécution est suspendue jusqu'à ce que le moniteur soit acquis ou qu'une InterruptedException se produise. Lorsque notify() est appelé, le moniteur est libéré.

Prenons un scénario si wait() et notify() étaient placés dans la classe Thread au lieu de la classe Object. A un moment donné dans le code, currentThread.wait() est appelé et ensuite un objet anObject est accessible.

//.........
currentThread.wait();
anObject.setValue(1);
//.........

Lorsque currentThread.wait() est appelé, le moniteur de currentThread est demandé et aucune autre exécution n'est effectuée jusqu'à ce que le moniteur soit acquis ou qu'une InterruptedException se produise. Maintenant, pendant l'état d'attente, si une méthode foo() d'un autre objet anotherObject résidant à currentThread est appelé à partir d'un autre thread, il est bloqué même si la méthode appelée foo() n'a pas accès anObject . Si la première méthode wait() a été appelée sur anObject au lieu du thread lui-même, d'autres appels de méthodes (n'accédant pas à l'information de l anObject ) sur des objets résidant dans le même thread ne seraient pas bloqués.

Ainsi, l'appel des méthodes wait() et notify() sur la classe Object (ou ses sous-classes) fournit une plus grande concurrence et c'est pourquoi ces méthodes sont dans la classe Object, et non dans la classe Thread.

0voto

kgiannakakis Points 62727

Lire aquí pour une explication de wait and notify.

Il serait toutefois préférable d'éviter ces éléments dans vos applications et d'utiliser les nouvelles versions de la norme java.util.concurrent paquet.

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