Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

Blocked 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.

like image 343
Peter Lee Avatar asked Sep 02 '25 10:09

Peter Lee


2 Answers

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.

like image 175
aNish Avatar answered Sep 04 '25 22:09

aNish


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.)

like image 43
rsp Avatar answered Sep 05 '25 00:09

rsp