Comment déterminer si un objet est verrouillé (synchronisé) afin de ne pas bloquer en Java?
J'ai un processus qui contient un tableau en mémoire avec un jeu d'enregistrements (recordA, recordB, etc...)
Maintenant, ce processus peut lancer plusieurs threads qui affectent les enregistrements, et parfois on peut avoir 2 threads tentent d'accéder à l'enregistrement de même - cette situation doit être rejetée. Spécifiquement si un enregistrement est VERROUILLÉ par un fil, je veux l'autre fil à l'avortement (je ne veux pas BLOQUER ou d'ATTENTE).
Actuellement je fais quelque chose comme ceci:
synchronized(record)
{
performOperation(record);
}
Mais c'est me causer des problèmes ... parce que tout de Fabrication1 effectue l'opération, si Process2 arrive blocs/l'attend sur le synchronisée instruction et lors de Fabrication1 est terminé, il effectue l'opération. Au lieu de cela, je veux quelque chose comme ceci:
if (record is locked)
return;
synchronized(record)
{
performOperation(record);
}
Des indices sur la façon dont ceci peut être accompli?
Toute aide serait grandement appréciée.
Merci,
Vous devez vous connecter pour publier un commentaire.
Une chose à noter est que le instant vous recevoir de telles informations, il est éventé. En d'autres termes, vous pourriez être dit que nul n'a le verrou, mais ensuite, lorsque vous essayez d'acquérir, vous bloquer parce qu'un autre thread a pris la serrure entre les vérifier et tenter de l'acquérir.
Brian est juste à point à
Lock
, mais je pense que ce que vous voulez vraiment est sontryLock
méthode:Vous pouvez également appeler
tryLock
avec une quantité de temps à attendre - de sorte que vous pourraient tenter en acquérir pour un dixième de seconde, puis abandonner si vous ne pouvez pas l'obtenir (par exemple).(Je pense que c'est dommage que l'API Java n'est pas pour autant que je suis au courant - fournir les mêmes fonctionnalités pour le "built-in" de verrouillage, comme le
Monitor
classe dans .NET. Puis de nouveau, il ya beaucoup d'autres choses que je n'aime pas dans les deux plates-formes quand il s'agit de filetage - chaque objet ayant potentiellement un moniteur, par exemple!)if (lock.tryLock())
essentiellement.Prendre un coup d'oeil à la Verrouillage objets introduit dans Java 5 simultanéité des paquets.
par exemple
La ReentrantLock objet est essentiellement de faire la même chose que le traditionnel
synchronized
mécanisme, mais avec plus de fonctionnalités.EDIT: Comme Jon l'a noté, le
isLocked()
méthode vous dit à cet instant, et par la suite que les informations de date. Le tryLock() méthode de donner plus de fiabilité de fonctionnement (note vous pouvez l'utiliser avec un délai d'expiration ainsi)EDIT #2: Exemple comprend maintenant
tryLock()/unlock()
pour plus de clarté.Tandis que l'approche ci-dessus à l'aide d'un Verrou d'objet est la meilleure façon de le faire, si vous avez d'être en mesure de vérifier de verrouillage à l'aide d'un moniteur, il peut être fait. Cependant, il ne viennent avec un avertissement de santé publique, car la technique n'est pas portable pour non Oracle de machines virtuelles Java et il peut se casser à l'avenir VM versions comme il n'est pas pris en charge API publique.
Voici comment le faire:
Mon conseil serait d'utiliser cette méthode uniquement si vous ne pouvez pas restructurer le code à utiliser java.util.simultanées de Verrouiller des objets pour cela, et si vous êtes en cours d'exécution sur un Oracle VM.
J'ai trouvé cela, nous pouvons utiliser
Thread.holdsLock(Object obj)
pour vérifier si un objet est verrouillé:Noter que
Thread.holdsLock()
retournefalse
si le verrou est détenu par quelque chose et le thread appelant n'est pas le fil qui détient le verrou.Pendant que le Verrou réponses sont très bon, je pensais que je poste une alternative en utilisant une autre structure de données. Essentiellement, vos différents threads veulent savoir quels enregistrements sont verrouillés et qui ne le sont pas. Une façon de le faire est de garder une trace de l'verrouillé dossiers et assurez-vous que la structure de données a le droit d'opérations atomiques pour ajouter des enregistrements à la verrouillés ensemble.
Je vais utiliser CopyOnWriteArrayList comme exemple parce que c'est moins "magique" pour l'illustration. CopyOnWriteArraySet est plus approprié de la structure. Si vous avez des tas de dossiers verrouillés dans le même temps, en moyenne, il peut y avoir des implications sur les performances de ces implémentations. Un correctement synchronisés HashSet serait trop de travail et les serrures sont de courte durée.
Fondamentalement, l'utilisation de code devrait ressembler à ceci:
Il vous permet d'éviter d'avoir à gérer un verrouillage par enregistrement et offre un lieu unique devrait effacement de tous les verrous nécessaires pour une raison quelconque. D'autre part, si jamais vous avez plus d'une poignée de dossiers alors un véritable HashSet avec la synchronisation peut faire de mieux depuis l'ajout/suppression de look-up sera en O(1) au lieu de linéaire.
Juste une façon différente de voir les choses. Tout dépend de ce que votre réelle de filetage exigences. Personnellement, je voudrais utiliser une des Collections.synchronizedSet( new HashSet ()), car il sera très vite... la seule implication est que les threads peuvent produire quand ils n'aurait pas autrement.
Lock
classe, je suppose.Une autre solution de contournement est (dans le cas où vous n'ont pas de chance avec les réponses données ici )est à l'aide de délais d'attente. c'est à dire en dessous renvoie la valeur null après 1 seconde de la pendaison:
Merci pour cela, il m'a aidé à résoudre une situation de concurrence. Je l'ai changé un peu de vêtements à la fois de la ceinture et des bretelles.
Donc, voici ma suggestion pour UNE AMÉLIORATION de la accepté de répondre:
Vous pouvez vous assurer que vous obtenez un accès sûr à l'
tryLock()
méthode en faisant quelque chose comme ceci:Cela permettrait d'éviter la situation où vous pourriez obtenir deux appels
tryLock()
au presque en même temps, de sorte que le retour à être potentiellement doute plein. J'aimerais maintenant si je me trompe, je suis peut-être plus de cautios ici. Mais hey! Mon boulot est stable maintenant :-)..Lire plus sur mes questions de développement à mon Blog.