why java.util.HashMap.getEntry can block my program?
my program had been blocked , I used the jstack commander to analyze, the following thread took the lock "0x0000000603f02ae0" , and others threads couldn't fetch the lock.
I had waited at least one hour, but the thread didn't unlock , my question is why the thread'state is RUNNING, and stop at java.util.HashMap.getEntry(HashMap.java:347) ? it is oracle(sun) JDK's bug ?my jdk version :
java version "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b06) Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)The thread info:
"PandoraScheduleTrigger-thread-5" prio=10 tid=0x00000000443b0800 nid=0x5804 runnable [0x0000000043722000] java.lang.Thread.State: RUNNABLE at java.util.HashMap.getEntry(HashMap.java:347) at java.util.HashMap.containsKey(HashMap.java:335) at com.youlongqingfeng.pandora.context.ArmiesContext._getArmy(ArmiesContext.java:239) at com.youlongqingfeng.pandora.context.ArmiesContext.getArmiesByCityId(ArmiesContext.java:169) at com.youlongqingfeng.pandora.model.City.getTotalApplianceMap(City.java:4519) at com.youlongqingfeng.pandora.model.City.calculateMemoryResource(City.java:4636) at com.youlongqingfeng.pandora.model.City.buildTaskFinish(City.java:1089) at com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit.buildTaskFinish(ZhouMapResourceUnit.java:1618) - locked <0x0000000603f02ae0> (a com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit) at com.youlongqingfeng.pandora.trigger.BuildTrigger.innerRun(BuildTrigger.java:39) at com.youlongqingfeng.gameserver.utils.threadpool.CancelTrigger.run(CancelTrigger.java:34)Blocke开发者_开发百科d thread dump:
"PandoraScheduleTrigger-thread-3" prio=10 tid=0x0000000044c7c000 nid=0x5802 waiting for monitor entry [0x0000000043520000] java.lang.Thread.State: BLOCKED (on object monitor) at com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit.armiesGroupReturnBack(ZhouMapResourceUnit.java:2279) - waiting to lock <0x0000000603f02ae0> (a com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit) at com.youlongqingfeng.pandora.trigger.ArmyGroupArrivedTrigger.innerRun(ArmyGroupArrivedTrigger.java:53) at com.youlongqingfeng.gameserver.utils.threadpool.CancelTrigger.run(CancelTrigger.java:34) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)
thank you.
Actually, you could have used ConcurrentHashMap instead of HashMap. HashMap will run into block state when different threads access the map in a loop or something. A ConcurrentHashMap can be used effectively. It is synchronized and efficient. It does not lock the complete Map, it just locks the current bucket which is accessed.
Some things to consider:
you are using
HashMap
, which is not synchronized itself. do you synchronize access to the map in your code, at all access points? If you did not, it is possible that concurrent access to the map corrupted the internal data resulting in unpredictable behaviour.one thread has a lock, the other is trying to get it. is it possible that you have a situation where 2 locks are involved where 2 threads are waiting for the other to release the lock they need before they release the one they locked? (thread 1 locked a, waits for b + thread 2 locked b waits for a -> deadlock.)
Are you sure the thread stop at getEntry ? The state is runnable, so I suppose it's run ? You catch with jstack at this step, it's all. I suppose there is sort of infinite loop under the ZhouMapResourceUnit.buildTaskFinish, and the lock is never released.
Use Hashtable if there are multiple threads and HashMap if there is only a single thread.
精彩评论