2010-08-07 3 views
3

mon programme avait été bloqué, j'ai utilisé le commandant jstack pour analyser, le thread suivant a pris le verrou "0x0000000603f02ae0", et d'autres threads ne pouvaient pas aller chercher le verrou.
J'avais attendu au moins une heure, mais le fil n'a pas déverrouillé, ma question est pourquoi l'état du thread est en cours d'exécution, et arrêter à java.util.HashMap.getEntry (HashMap.java:347)? c'est le bug de l'oracle (soleil) de JDK?pourquoi java.util.HashMap.getEntry peut bloquer mon programme?

ma version jdk:
java version "1.6.0_21"
Java (TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot (TM) 64 bits serveur VM (build 17.0- b16, mode mixte)

Les informations du fil:
"PandoraScheduleTrigger-fil-5" prio = 10 tid = 0x00000000443b0800 nid = 0x5804 runnable [0x0000000043722000] java.lang.Thread.State: rUNNABLE à java.util .HashMap.getEntry (HashMap.java:347) at java.util.HashMap.containsKey (HashMap.java:335) à com.youlongqingfeng.pandora.context.ArmiesContext._getArmy (ArmiesContext.java:239) à com.youlongqingfeng.pandora.context.ArmiesContext.getArmiesByCityId (ArmiesContext.java:169) à com.youlongqingfeng.pandora.model. City.getTotalApplianceMap (City.java:4519) à com.youlongqingfeng.pandora.model.City.calculateMemoryResource (City.java:4636) à com.youlongqingfeng.pandora.model.City.buildTaskFinish (City.java:1089) à com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit.buildTaskFinish (ZhouMapResourceUnit.java:1618) - verrouillé < 0x0000000603f02ae0> (a com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit) à com.youlongqingfeng. pandora.trigger. BuildTrigger.innerRun (BuildTrigger.java:39) à com.youlongqingfeng.gameserver.utils.threadpool.CancelTrigger.run (CancelTrigger.java:34)

thread dump bloqué:

« PandoraScheduleTrigger-fil-3 "prio = 10 tid = 0x0000000044c7c000 nid = 0x5802 en attente de l'entrée du moniteur [0x0000000043520000] java.lang.Thread.State: BLOCKED (sur le moniteur d'objet) at com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit.armiesGroupReturnBack (ZhouMapResourceUnit. java: 2279) - en attente de verrouiller < 0x0000000603f02ae0> (un com.youlongqingfeng.pandora.map.unit.ZhouMapResourceU nit) à com.youlongqingfeng.pandora.trigger.ArmyGroupArrivedTrigger.innerRun (ArmyGroupArrivedTrigger.java:53) à com.youlongqingfeng.gameserver.utils.threadpool.CancelTrigger.run (CancelTrigger.java:34) à java.util. simult.Executors $ RunnableAdapter.call (Executors.java:441) à java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask.java:303) à java.util.concurrent.FutureTask.run (FutureTask.java: 138) à java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access 301 $ (ScheduledThreadPoolExecutor.java:98) à java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run (ScheduledThreadPoolExecutor.java:207) à java.util.concurrent .ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:886) à java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:908) à java.lang.Thread.run (Thread.java:619)

merci.

+0

Quels autres threads s'exécutent en même temps - en particulier, un autre thread accède-t-il à la même ressource? –

+0

Voir http://stackoverflow.com/questions/10219724/vaadin-blocking-in-java-util-hasmap – Vadzim

Répondre

3

Certaines choses à considérer:

  • vous utilisez HashMap, qui est lui-même pas synchronisé. synchronisez-vous l'accès à la carte dans votre code, à tous les points d'accès? Si vous n'avez pas, il est possible que l'accès simultané à la carte corrompu les données internes entraînant un comportement imprévisible.

  • Un thread a un verrou, l'autre essaie de l'obtenir. Est-il possible que vous ayez une situation où 2 verrous sont impliqués où 2 threads attendent que l'autre libère le verrou dont ils ont besoin avant de libérer celui qu'ils ont verrouillé? (1 fil verrouillé a, attend b + 2 fils d'attente verrouillé b pour une -> impasse.)

+1

merci, j'ai la réponse, parce que le thread a le ReadLock, mais j'ai écrit quelques données sur la carte , donc le bug est survenu. –

+0

J'ai trouvé le même bug dans mybatis ~ getEntry juste boucle forever.so triste – wener

+0

@PeterLee Hey, j'ai une situation très similaire dans PROD avec un HashMap accédé dans un processus multi-Thread où tous les 5 threads se verrouillent 'java. util.HashMap.getEntry (HashMap.java:480) '. Je veux comprendre votre déclaration à propos de ReadLock. Voulez-vous dire que vous étiez juste en train de mettre des éléments dans le HashMap au moment de la lecture des éléments? ou vous avez eu une implémentation dans votre code de 'ReadWriteLock.readLock()' pour obtenir les éléments de la carte et rien n'a été fait pour 'mettre 'l'élément dans? – vadimbog

2

Etes-vous sûr de l'arrêt de fil à getEntry? L'état est runnable, donc je suppose qu'il est exécuté? Vous attrapez avec jstack à cette étape, c'est tout. Je suppose qu'il y a une sorte de boucle infinie sous le ZhouMapResourceUnit.buildTaskFinish, et le verrou n'est jamais libéré.

0

Utilisez Hashtable s'il y a plusieurs threads et HashMap s'il n'y a qu'un seul thread.

+0

Hashtable est lent, j'utilise le readWriteLock pour le résoudre, merci. –

5

En fait, vous auriez pu utiliser ConcurrentHashMap au lieu de HashMap. HashMap se mettra en état de blocage lorsque différents threads accèdent à la carte dans une boucle ou quelque chose. Un ConcurrentHashMap peut être utilisé efficacement. C'est synchronisé et efficace. Il ne verrouille pas la carte complète, il verrouille simplement le compartiment auquel on accède.

Questions connexes