Ma compréhension des blocs Java synchronized() est que, si un thread possède déjà un verrou sur un objet, il peut entrer un bloc différent synchronisé sur le même objet (synchronisation rentrante) . En dessous, je crois que la JVM utilise un nombre de références pour incrémenter/décrémenter le nombre de fois qu'un thread a acquis un verrou, et que le verrou n'est libéré que lorsque le compte est nul.Java Wait/Notifier dans les blocs synchronisés réentrants
Donc ma question est, si l'on rencontre un morceau de code qui ressemble à ceci:
synchronized(this)
{
if (condition == WAITING)
{
synchronized(this)
{
condition = COMPLETE;
notify();
try
{
wait();
}
catch(InterruptedException e)
{
}
}
}
else
condition = READY;
}
ce qui se passe surtout quand attente() est appelée? Est-ce que cela ne fait que décrémenter le compte, ou est-ce qu'il libère le verrou quel que soit le nombre? Dans le premier cas, il me semble que cela produira un interblocage si une rentrée de verrouillage s'est produite, car il possédera toujours le verrou et attendra donc toujours sur un autre thread qui l'attend.
Dans le second cas, je ne vois pas vraiment quel est le point du second bloc synchronisé.
La documentation attente() dit
« Le thread courant doit posséder le moniteur de cet objet. Le fil libère la propriété de ce moniteur et attend jusqu'à ce qu'un autre fil informe les threads en attente sur l'écran de cet objet pour se réveiller soit par un appel à la notifier ou la méthode de notifyAll. le fil attend alors jusqu'à ce qu'il puisse réobtenir la propriété du moniteur et reprend l'exécution, »
donc je pense que le second cas est correcte, mais Je peux me tromper. Est-ce qu'il me manque quelque chose, ou est-ce que je viens juste de rencontrer un bloc synchronisé redondant qui pourrait tout aussi bien être retiré du code?
Si vous voyez un code comme celui-ci (dont certains ne sont pas compilés), je vous suggère de le supprimer et de le réécrire. Note: la première fois que vous appelez notifier, rien ne se passera car aucun thread ne sera en attente. La deuxième fois, vous n'appelez pas notifier car la condition a changé, donc votre premier thread attendra pour toujours. –
J'ai (mal) édité le code pour le simplifier à titre d'exemple. La condition et les erreurs incompilables étaient moi, pas le code/problème lui-même. En outre, la condition est mise à jour ailleurs, par un autre thread. Le jist de base du code est pour un thread en attente d'un autre thread à compléter pour être averti que la condition a changé. Il appelle alors notifier ailleurs quand il a fini. – user2725525
Pourquoi ne pas le réécrire pour utiliser un Futures afin de savoir quand un thread est terminé? –