почему java.util.HashMap.getEntry может заблокировать мою программу? - PullRequest
3 голосов
/ 07 августа 2010

моя программа была заблокирована, я использовал анализатор jstack, следующий поток взял блокировку "0x0000000603f02ae0", а другие потоки не смогли получить блокировку.
Я ждал, по крайней мере, один час, но поток не разблокировался. Мой вопрос: почему состояние потока выполняется, и остановка на java.util.HashMap.getEntry (HashMap.java:347)? это ошибка оракула (солнца) JDK?

моя версия JDK:
Java-версия "1.6.0_21"
Java (TM) SE Runtime Environment (сборка 1.6.0_21-b06)
Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 17.0-b16, смешанный режим)

Информация о теме:
"PandoraScheduleTrigger-thread-5" prio = 10 tid = 0x00000000443b0800 nid = 0x5804 runnable [0x0000000043722000] java.lang.Thread.State: RUNNABLE в java.util.HashMap.getEntry (HashMap.java:347) в 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) - заблокирован <0x0000000603f02ae0> (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)

Дамп заблокированного потока:

"PandoraScheduleTrigger-thread-3" prio = 10 tid = 0x0000000044c7c000 nid = 0x5802 ожидает записи монитора [0x0000000043520000] java.lang.Thread.State: BLOCKED (на объектном мониторе) в com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit.armiesGroupReturnBack (ZhouMapResourceUnit.java:2279) - ожидание блокировки <0x0000000603f02ae0> (com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit) в com.youlongqingfeng.pandora.trigger.ArmyGroupArrivedTrigger.innerRun (ArmyGroupArrivedTrigger.java:53) на com.youlongqingfeng.gameserver.utils.threadpool.CancelTrigger.run (CancelTrigger.java:34) в java.util.concurrent.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) at java.lang.Thread.run (Thread.java:619)

спасибо.

Ответы [ 4 ]

5 голосов
/ 08 августа 2010

На самом деле, вы могли бы использовать ConcurrentHashMap вместо HashMap. HashMap переходит в состояние блока, когда разные потоки обращаются к карте в цикле или чем-то еще ConcurrentHashMap может использоваться эффективно. Это синхронизировано и эффективно. Он не блокирует полную карту, он просто блокирует текущую корзину, к которой осуществляется доступ.

3 голосов
/ 07 августа 2010

Некоторые вещи, которые следует учитывать:

  • вы используете HashMap, который не синхронизирован сам по себе.Вы синхронизируете доступ к карте в своем коде на всех точках доступа?Если вы этого не сделали, возможно, что одновременный доступ к карте повредил внутренние данные, что привело к непредсказуемому поведению.

  • один поток имеет блокировку, другой пытается ее получить.возможно ли, что у вас есть ситуация, когда задействованы 2 блокировки, когда 2 потока ожидают, пока другой освободит блокировку, в которой они нуждаются, прежде чем освободят блокированную?(поток 1 заблокирован a, ожидает b + поток 2 заблокирован b ожидает a -> взаимоблокировка.)

2 голосов
/ 07 августа 2010

Вы уверены, что поток останавливается на getEntry ? Состояние работоспособно , так что я полагаю, оно запущено? На этом шаге вы ловите с помощью jstack, вот и все. Я полагаю, что в ZhouMapResourceUnit.buildTaskFinish есть своего рода бесконечный цикл, и блокировка никогда не снимается.

0 голосов
/ 07 августа 2010

Используйте Hashtable, если есть несколько потоков, и HashMap, если есть только один поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...