4

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.

Peter Lee
  • 1,011
  • 1
  • 10
  • 11
  • Which other threads are running at the same time - specifically, is there another thread that is accessing the same resource? – Will A Aug 07 '10 at 06:43
  • See http://stackoverflow.com/questions/10219724/vaadin-blocking-in-java-util-hasmap – Vadzim May 20 '14 at 09:28

4 Answers4

5

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.

aNish
  • 1,079
  • 6
  • 11
3

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

rsp
  • 23,135
  • 6
  • 55
  • 69
  • 1
    thank you , I have got the answer, because the thread got the ReadLock,but I wrote some data in the map , so the bug occured. – Peter Lee Aug 07 '10 at 10:49
  • I found the same bug in mybatis~ getEntry just loop forever.so sad – wener Oct 18 '14 at 01:15
  • @PeterLee Hey, I have a very similar situation in PROD with a HashMap accessed in a Multi-Thread process where all 5 threads are getting locked `at java.util.HashMap.getEntry(HashMap.java:480)`. I want to understand you statement about ReadLock. Do you mean that you were just `put`ing elements in the HashMap at the time elements were read? or you were having an implementation in your code of `ReadWriteLock.readLock()` for getting the items from map and nothing was done for `put`ing the element in? – vadimbog May 30 '15 at 05:52
2

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.

Istao
  • 7,425
  • 6
  • 32
  • 39
0

Use Hashtable if there are multiple threads and HashMap if there is only a single thread.

khairil
  • 210
  • 1
  • 5