multithreading - 为什么 java.util.HashMap.getEntry 可以阻止我的程序?

标签 multithreading thread-safety java threadpool

我的程序被阻塞了,我用jstack commander分析,下面的线程拿了锁“0x0000000603f02ae0”,其他线程拿不到锁。
我等了至少一个小时,但线程没有解锁,我的问题是为什么线程的状态是 RUNNING,并停止在 java.util.HashMap.getEntry(HashMap.java:347) ?是 oracle(sun) JDK 的 bug 吗?

我的jdk版本:
Java 版本“1.6.0_21”
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64 位服务器 VM(构建 17.0-b16,混合模式)

线程信息:
“PandoraScheduleTrigger-thread-5”prio=10 tid=0x00000000443b0800 nid=0x5804 可运行 [0x0000000043722000] java.lang.Thread.State: 可运行 在 java.util.HashMap.getEntry(HashMap.java:347) 在 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) 在 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(在对象监视器上) at com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit.armiesGroupReturnBack(ZhouMapResourceUnit.java:2279) - 等待锁定<0x0000000603f02ae0>(一个com.youlongqingfeng.pandora.map.unit.ZhouMapResourceUnit) at 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) 在 java.lang.Thread.run(Thread.java:619)

谢谢。

最佳答案

实际上,您可以使用 ConcurrentHashMap 而不是 HashMap。 当不同的线程在循环中访问映射时,HashMap 将进入 block 状态。可以有效地使用 ConcurrentHashMap。它是同步和高效的。它不锁定完整的Map,它只锁定当前访问的桶。

关于multithreading - 为什么 java.util.HashMap.getEntry 可以阻止我的程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3429420/

相关文章:

java - 为什么这不起作用 - 使用 Junit 的参数化数据对同步方法进行单元测试?

multithreading - iOS 8.3上的CoreData多线程崩溃

python - 为什么 python threading.Thread 对象有 'start' ,但没有 'stop' ?

java - ExecutorService 有 n 个线程和 n 个相应的对象

java - 动画线程和 EDT

java - AtomicInteger 和 Math.max

java - CopyOnWriteArrayList 或 Vector

java - Eclipse界面链接打开相关文件

java - Couchbase - 创建 View 并立即访问其数据

java - 同步方法