Chaque fois que vous avez plusieurs verrous A, B et C, vous pouvez avoir une impasse si vous ne garantissez pas que votre code tente d'acquérir lesdits verrous dans le même ordre.
final Lock A = new ReentrantLock();
final Lock B = new ReentrantLock();
final Lock C = new ReentrantLock();
A, B, C ou C, B, A ou A, C, B - Peu importe tant que l'ordre est cohérent.
Un problème se pose lorsque vous avez un chemin de code essayant: a, b, c et un autre essayant pour c, b, a.
Comme vous pouvez probablement le deviner, car A et C sont tous deux détenus, l'un des deux obtiendra B, puis les deux seront imprégnés. (AKA vous avez un cycle dans le graphique de verrouillage des ressources)
L'impasse formellement parlant peut surgir seulement si Toutes les conditions suivantes soutiennent:
- Pas de préemption: le système ne sera pas gratuit après l'allocation; Ils ne peuvent être libérés que par le processus de maintien.
- Attente circulaire: discuté ci-dessus.
- Exclusion mutuelle: un seul processus peut utiliser une ressource à tout moment.
- Tenue de ressources: un processus détient actuellement au moins une ressource et demande / attend des ressources supplémentaires qui sont détenues par un autre processus.
La meilleure solution consiste à s'assurer que la commande est cohérente ou à verrouiller à un niveau plus élevé (unique). Une autre option consiste à utiliser une bibliothèque de verrouillage qui sera dénoncée tout en essayant de verrouiller (ou d'utiliser des conditions et d'écrire votre propre wrapper qui le fait). Mais cette approche n'est pas pour les faibles de cœur. Une certaine mise en œuvre de cela attendra un temps aléatoire et réessayera, mais cela peut être très inefficace à mesure que le nombre de verrous augmente.
Ressources:
- Voici un article pratique sur l'analyse de l'impasse en Java qui pourrait vous intéresser:http://www.journaldev.com/1058/java-deadlock-example-and-how-to-analyze-deadlock-situation
- Vous pouvez également utiliser des outils open source comme JCarder pour trouver une impasse:http://www.jcarder.org/ Ce qui pour les programmes avec de grands vidages peut être plus facile que d'essayer d'obtenir des fichiers de vidage.
PS Je n'ai pas vraiment lu beaucoup de votre code car il est mal formaté et n'est pas un exemple minimal (c'est-à-dire trop verbeux pour nos fins ici). Mais ce conseil devrait vous répondre à un point de vue théorique.