gpt4 book ai didi

java - ConcurrentHashMap 是否可能为 "deadlock"?

转载 作者:IT老高 更新时间:2023-10-28 20:35:31 26 4
gpt4 key购买 nike

我们遇到了一个关于 ConcurrentHashMap 的奇怪问题,其中两个线程似乎正在调用 put(),然后在方法 Unsafe 中永远等待。公园()。从外面看,它就像 ConcurrentHashMap 内部的死锁。

到目前为止,我们只见过这种情况发生过一次。

谁能想到可能导致这些症状的任何事情?

编辑:相关线程的线程转储在这里:

"[redacted] Thread 2" prio=10 tid=0x000000005bbbc800 nid=0x921 waiting on condition [0x0000000040e93000]   java.lang.Thread.State: WAITING (parking)    at sun.misc.Unsafe.park(Native Method)    - parking to wait for  <0x00002aaaf1207b40> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)    at java.util.concurrent.ConcurrentHashMap$Segment.put(ConcurrentHashMap.java:417)    at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:883)    at [redacted]"[redacted] Thread 0" prio=10 tid=0x000000005bf38000 nid=0x91f waiting on condition [0x000000004151d000]   java.lang.Thread.State: WAITING (parking)    at sun.misc.Unsafe.park(Native Method)    - parking to wait for  <0x00002aaaf1207b40> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)    at java.util.concurrent.ConcurrentHashMap$Segment.put(ConcurrentHashMap.java:417)    at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:883)    at [redacted]

最佳答案

我不认为这就是您的情况,但是可以使用 ConcurrentHashMap 的单个实例编写死锁,而且只需要一个线程!让我卡了好一阵子。

假设您使用的是 ConcurrentHashMap<String, Integer>计算直方图。你可以这样做:

int count = map.compute(key, (k, oldValue) -> {
return oldValue == null ? 1 : oldValue + 1;
});

效果很好。

但是假设你决定改为这样写:

int count = map.compute(key, (k, oldValue) -> {
return map.putIfAbsent(k, 0) + 1;
});

您现在将得到一个带有这样堆栈的 1 线程死锁:

Thread [main] (Suspended)   
owns: ConcurrentHashMap$ReservationNode<K,V> (id=25)
ConcurrentHashMap<K,V>.putVal(K, V, boolean) line: not available
ConcurrentHashMap<K,V>.putIfAbsent(K, V) line: not available
ConcurrentHashMapDeadlock.lambda$0(ConcurrentHashMap, String, Integer) line: 32
1613255205.apply(Object, Object) line: not available
ConcurrentHashMap<K,V>.compute(K, BiFunction<? super K,? super V,? extends V>) line: not available

在上面的示例中,很容易看出我们试图在原子修改内部修改映射,这似乎是个坏主意。但是,如果在调用 map.compute 之间有一百个事件回调堆栈帧和 map.putIfAbsent ,那么就很难追踪了。

关于java - ConcurrentHashMap 是否可能为 "deadlock"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3292577/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com