Pourquoi wait() doit résider dans un bloc synchronisé
L'application de l'appel d'Object.wait() dans un bloc synchronisé joue un rôle crucial objectif dans le modèle de concurrence de Java. Ne pas respecter cette restriction entraîne une IllegalMonitorStateException, mais comprendre la justification de cette contrainte est essentiel.
Raison de l'attente synchronisée()
wait() libère le moniteur associé à l’objet synchronisé. L'acquisition explicite du moniteur avant d'appeler wait() garantit que le thread appelant détient exclusivement le moniteur lorsque l'opération d'attente se produit. Cela garantit qu'aucun autre thread ne peut modifier l'état partagé pendant que le thread appelant est en attente.
Conséquences de Wait() en dehors d'un bloc synchronisé
Si wait() pouvait être invoqué en dehors d'un bloc synchronisé, cela pourrait entraîner divers problèmes. Considérons le scénario suivant :
Exemple : file d'attente de blocage
Imaginez une file d'attente de blocage qui permet à un thread consommateur de récupérer des éléments d'une file d'attente et à un thread producteur d'ajouter des éléments. à la file d'attente. Sans synchronisation :
class BlockingQueue { Queue<String> buffer = new LinkedList<>(); void take() throws InterruptedException { while (buffer.isEmpty()) { // Suspend thread without acquiring the monitor wait(); } } }
Problèmes potentiels :
Exigence de synchronisation universelle
Ce problème de synchronisation ne se limite pas à l'exemple de file d'attente de blocage. Tout scénario impliquant une communication par thread utilisant wait() et notify() nécessite une synchronisation pour éviter les conditions de concurrence et les blocages potentiels.
Accord entre le serveur et le notificateur
Attente synchronisée() garantit que le thread serveur (consommateur) et le thread notificateur (producteur) s'accordent sur l'état de la ressource partagée (prédicat). Cet accord garantit que le serveur vérifie correctement le prédicat avant d'attendre et ne manque aucune notification pendant cette période vulnérable.
Dans l'exemple ci-dessus, le prédicat est buffer.isEmpty(). La synchronisation garantit que le thread consommateur ne se suspend que lorsque le tampon est vraiment vide.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!