Savez - vous vraiment quand le verrouillage de synchronisation Java sera libéré?

InfoQ 2022-05-14 11:55:15 阅读数:210

savezvousvraimentquandle
Autres réponses:

waitLe Thread in n'est pas en concurrence avec le verrouillage de l'objet. Pour autant que je sache,,A commencé parce quewaitMéthodes,Le thread est dans le pool d'attente pour cet objet,

Et puis,Seulement pour appeler l'objet à nouveaunotifyAll()(Réveillez tous les fils dans le pool d'attente)Ounotify()(Fil de réveil aléatoire,Supposons que le fil qui nous a réveillés),Le thread entre dans le pool de verrouillage de l'objet.

Les objets dans le pool de serrures rivalisent pour les serrures d'objets,Les Threads hautement prioritaires ont une forte probabilité d'obtenir le verrouillage de l'objet,Si le thread n'est pas en concurrence avec,Il sera toujours dans la piscine de verrouillage,Seul le thread appelle à nouveauwaitMéthodes,Il retourne dans la piscine d'attente..

[](()javaQuand le Multithreading libère - t - il la serrure—wait()、notify()



Parce qu'attendre un Thread de verrouillage seulement après avoir obtenu cette serrure,Pour reprendre l'opération,Il est donc important que le thread qui tient la serrure libère la serrure quand elle n'est pas nécessaire.Dans les cas suivants:,Le fil qui tient la serrure libère la serrure:

  • Terminer la synchronisation des blocs de code.
  • Lors de l'exécution du bloc de code de synchronisation,Le thread s'est arrêté en raison d'une exception rencontrée.
  • Lors de l'exécution du bloc de code de synchronisation,L'objet auquel appartient la serrure a été exécutéwait()Méthodes,Ce fil libère la serrure,Faire un pool d'attente pour l'objet.

En plus de ce qui précède,Tant que l'affaire avec la serrure n'a pas fini d'exécuter le bloc de code de synchronisation,Il n'y aurait pas de déverrouillage.Par conséquent, dans les cas suivants,Le fil ne libère pas la serrure:

  • Lors de l'exécution du bloc de code de synchronisation,Mise en œuvreThread.sleep()Méthodes,Le thread actuel abandonneCPU, Commence à dormir , Pas de déverrouillage pendant le sommeil .
  • Lors de l'exécution du bloc de code de synchronisation,Mise en œuvreThread.yield()Méthodes,Le thread actuel abandonneCPU,Mais il ne libère pas la serrure..
  • Lors de l'exécution du bloc de code de synchronisation, Un autre thread a exécuté suspend()Méthodes, Le thread actuel est en pause ,Mais il ne libère pas la serrure..Mais...ThreadClassesuspend()La méthode a été abandonnée.

Une règle générale pour éviter l'impasse est : Lorsque plusieurs Threads doivent accéder à une ressource partagée A、BEtCHeure, Assurez - vous que chaque fil les accède dans le même ordre , Comme visiter d'abord A,Re - visitBEtC.

  • java.lang.Object Deux méthodes de communication par fil sont disponibles dans la classe :wait()Etnotify().Il convient de noter que oui,wait() La méthode doit être placée dans un cycle ,Parce que dans un environnement multithreadé, L'état de l'objet partagé peut changer à tout moment . Quand un thread dans le pool d'attente de l'objet est réveillé , Il n'est pas nécessaire de reprendre les opérations immédiatement , Attendez que ce fil ait la serrure et CPUPour continuer, Peut - être que l'état de l'objet a changé .
  • AppelezobjDewait(), notify()Avant la méthode,Vous devez obtenirobjVerrouillage,Ça doit être écrit danssynchronized(obj) {…} Dans le fragment de code.

# Appelezobj.wait()Après,ThreadAIl a été libéréobjVerrouillage,Sinon, ThreadBNon disponibleobjVerrouillage,Je ne peux pas être là.synchronized(obj) {…} Réveil dans le fragment de codeA.

# Quandobj.wait()Après le retour de la méthode,ThreadA Besoin d'obtenir à nouveau objVerrouillage,Pour continuer.

# SiA1,A2,A3Tout est là.obj.wait(),EtBAppelezobj.notify()Je ne peux que réveillerA1,A2,A3Un des( Lequel est spécifique par JVMDécide que).

# obj.notifyAll()Pour réveiller toutA1,A2,A3,Mais pour continuerobj.wait()La déclaration suivante de,Vous devez obtenirobjVerrouillage,Donc,,A1,A2,A3Une seule chance d'obtenir la serrure pour continuer,Par exempleA1,Le reste doit attendreA1ReleaseobjL'exécution ne peut se poursuivre tant que la serrure n'est pas verrouillée.

# QuandBAppelezobj.notify/notifyAllQuand,B En attente objVerrouillage,Donc,,A1,A2,A3Bien que réveillée,Mais il n'y a toujours pasobjVerrouillage.Jusqu'àBSortiesynchronizedBloc,ReleaseobjDerrière la serrure,A1,A2,A3L'un d'eux a eu la chance d'obtenir la serrure pour continuer.

[](()wait()/sleep()La différence entre

------ 
《Grandes usines de première ligneJavaAnalyse des questions d'entrevue+Notes d'apprentissage pour le développement de l'arrière - plan+La dernière vidéo d'architecture+Document d'information sur le code source du projet en direct》Open Source gratuit Recherche de prestige Numéro public【Programmation avancée】
 ------------------------------------------------------------------------
Copyright:Cet article est[InfoQ]Établi,Veuillez apporter le lien original pour réimprimer,remercier。 https://fra.fheadline.com/2022/134/202205141147349709.html