2010-06-16 4 views
0

Je viens de jouer avec des threads en Java pour avoir la tête autour d'eux (ça semble être la meilleure façon de le faire) et maintenant comprendre ce qui se passe avec synchronize, wait() et notify().Est-ce qu'un thread appelle wait() sur deux verrous à la fois en Java (6)

Je suis curieux de savoir s'il existe un moyen d'attendre() sur deux ressources à la fois. Je pense que ce qui suit ne fait pas exactement ce que je pense (modifier: noter que l'habituel tandis que les boucles ont été laissées de cet exemple pour se concentrer uniquement sur la libération des deux ressources):

synchronized(token1) { 
    synchronized(token2) { 
     token1.wait(); 
     token2.wait(); //won't run until token1 is returned 
     System.out.println("I got both tokens back"); 
    } 
} 

Dans ce cas (très artificiel), le jeton2 sera conservé jusqu'à ce que token1 soit renvoyé, puis le token1 sera conservé jusqu'à ce que token2 soit renvoyé. Le but est de libérer à la fois token1 et token2, puis de reprendre quand les deux sont disponibles (notez que déplacer le token1.wait() en dehors de la boucle interne synchronisée n'est pas ce que je veux dire). Une boucle vérifiant si les deux sont disponibles pourrait être plus appropriée pour obtenir ce comportement (serait-ce proche de l'idée de double-vérifier le verrouillage?), Mais utiliserait des ressources supplémentaires - Je ne suis pas après une solution définitive puisque c'est juste pour satisfaire ma curiosité. Supposons simplement que les deux jetons représentent ici deux ressources distinctes que le thread doit utiliser en même temps, et que d'autres threads auront besoin des deux en même temps.

Répondre

2

Non, pas avec un verrou Java standard. Bien que je suppose que vous pourriez construire un tel verrou.

wait doit être appelé dans une boucle (wait peut spuriously réactivent, et dans la plupart des situations vous voulez la boucle de toute façon) while. Donc, une sorte de drapeau aurait plus de sens.

+0

Je suppose que vous voulez dire une sorte de drapeau au lieu de la deuxième serrure? Quelque chose comme 'while (! Flag) {token1.wait();}' –

2

L'exemple n'inclut pas la condition sur laquelle l'attente sera effectuée. Typiquement, l'attente ne se produira que jusqu'à ce que la condition soit remplie. En général, je pense que l'on pourrait accomplir ce que vous essayez de faire en ayant un seul verrou/attendre et en faisant abstraction du 'token1 et du token2' dans la logique conditionnelle.

Par exemple

synchronized(object) { 
    while ((!token1ConditionMet) && (!token2ConditionMet)) { 
     wait(); 
    } 
} 
Questions connexes