简体   繁体   English

“ConcurrentHashMap”可能会挂起吗?

[英]is it possible for `ConcurrentHashMap` to hang?

First I'll summarize what I've found so far. 首先,我将总结到目前为止我发现的内容。

  • This answer suggests that changing the concurrencyLevel parameter of ConcurrentHashMap 's constructor might help. 这个答案表明,更改ConcurrentHashMap的构造函数的concurrencyLevel参数可能会有所帮助。 I've tried that and my code still hanged. 我试过了,我的代码仍然被绞死了。
  • Answers here suggest that it could be a runtime bug. 这里的答案表明它可能是一个运行时错误。

What I'm trying to do: 我正在尝试做什么:

  • I have 10 worker threads running along with a main thread. 我有10个工作线程与主线程一起运行。 The worker threads will have to process many arrays to find the index of the max element in the array (if there are multiple max values, the first occurrence will be used). 工作线程必须处理许多数组以查找数组中max元素的索引(如果有多个最大值,则将使用第一个出现的值)。 Among these "many arrays," some of them can be duplicate, so I'm trying to avoid those full array scans to speed up the program. 在这些“许多阵列”中,其中一些可能是重复的,所以我试图避免那些完整的阵列扫描来加速程序。
  • The controller class contains a ConcurrentHashMap that maps the hash values of arrays to the corresponding max-element indices. 控制器类包含一个ConcurrentHashMap ,它将数组的哈希值映射到相应的max-element索引。
  • The worker threads will ask the controller class for the mapped index first before trying to calculate the index by doing full array scans. 在尝试通过执行完整阵列扫描来计算索引之前,工作线程将首先向控制器类询问映射索引。 In the latter case, the newly calculated index will be put into the map. 在后一种情况下,新计算的索引将被放入地图中。
  • The main thread does not access the hash map. 主线程不访问哈希映射。

What happened: 发生了什么:

  • My code will hang after 70,000 ~ 130,000 calls to getMaxIndex() . 在对getMaxIndex()进行70,000~130,000次调用后,我的代码将挂起。 This count is obtained by putting a log string into getMaxIndex() so it might not be exactly accurate. 这个计数是通过将一个日志字符串放入getMaxIndex()因此它可能不完全准确。
  • My CPU usage will gradually go up for ~6 seconds, and then it will go down to ~10% after peaked at ~100%. 我的CPU使用率将逐渐上升约6秒,然后在达到~100%达到峰值后下降到~10%。 I have plenty of unused memory left. 我还有很多未使用的内存。 (Does this look like deadlock?) (这看起来像僵局吗?)
  • If the code does not use map it works just fine (see getMaxIndex() version 2 below). 如果代码不使用map,它就可以正常工作(参见下面的getMaxIndex()版本2)。
  • I've tried to add synchronized to getMaxIndex() 's signature and use the regular HashMap instead, that also did not work. 我试图将synchronized添加到getMaxIndex()的签名并使用常规的HashMap ,这也没有用。
  • I've tried to use different initialCapacity values too (eg 50,000 & 100,000). 我也试过使用不同的initialCapacity值(例如50,000和100,000)。 Did not work. 不工作。

Here's my code: 这是我的代码:

// in the controller class
int getMaxIndex(@NotNull double[] arr) {
    int hash = Arrays.hashCode(arr);

    if(maxIndices.containsKey(hash)) {
        return maxIndices.get(hash);
    } else {
        int maxIndex =
            IntStream.range(0, arr.length)
                .reduce((a, b) -> arr[a] < arr[b] ? b : a)
                .orElse(-1); // -1 to let program crash

        maxIndices.put(hash, maxIndex);
        return maxIndex;
    }
}

The worker thread will call getMaxIndex() like this: return remaining[controller.getMaxIndex(arr)]; 工作线程将像这样调用getMaxIndex()return remaining[controller.getMaxIndex(arr)]; , remaining is just another int array. remaining的只是另一个int数组。

getMaxIndex() v2: getMaxIndex() v2:

int getMaxIndex(@NotNull double[] arr) {
    return IntStream.range(0, arr.length)
        .reduce((a, b) -> arr[a] < arr[b] ? b : a)
        .orElse(-1); // -1 to let program crash
}

JVM info in case it matters: JVM信息以防万一:

java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

EDIT : stack dump; 编辑 :堆栈转储; I used Phaser to synchronize the worker threads, so some of them appear to be waiting on the phaser, but pool-1-thread-2 , pool-1-thread-10 , pool-1-thread-11 , and pool-1-thread-12 do not appear to be waiting on the phaser. 我使用Phaser来同步工作线程,因此其中一些似乎正在等待相位器,但是pool-1-thread-2pool-1-thread-10pool-1-thread-11pool-1-thread-12似乎没有等待相位器。

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode):

"Attach Listener" #23 daemon prio=9 os_prio=0 tid=0x00007f0c54001000 nid=0x4da2 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"pool-1-thread-13" #22 prio=5 os_prio=0 tid=0x00007f0c8c2cb800 nid=0x4d5e waiting on condition [0x00007f0c4eddd000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e792f40> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-12" #21 prio=5 os_prio=0 tid=0x00007f0c8c2ca000 nid=0x4d5d waiting on condition [0x00007f0c4eede000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000775518738> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-11" #20 prio=5 os_prio=0 tid=0x00007f0c8c2c8000 nid=0x4d5c waiting on condition [0x00007f0c4efdf000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000775518738> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-10" #19 prio=5 os_prio=0 tid=0x00007f0c8c2c6000 nid=0x4d5b waiting on condition [0x00007f0c4f0e0000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000775518738> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-9" #18 prio=5 os_prio=0 tid=0x00007f0c8c2c4800 nid=0x4d5a waiting on condition [0x00007f0c4f1e1000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e7c74f8> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-8" #17 prio=5 os_prio=0 tid=0x00007f0c8c2c2800 nid=0x4d59 waiting on condition [0x00007f0c4f2e2000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e64fb78> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-7" #16 prio=5 os_prio=0 tid=0x00007f0c8c2c1000 nid=0x4d58 waiting on condition [0x00007f0c4f3e3000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e8b44c8> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-6" #15 prio=5 os_prio=0 tid=0x00007f0c8c2bf800 nid=0x4d57 waiting on condition [0x00007f0c4f4e4000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e5b4500> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-5" #14 prio=5 os_prio=0 tid=0x00007f0c8c2bd800 nid=0x4d56 waiting on condition [0x00007f0c4f5e5000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e836958> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-4" #13 prio=5 os_prio=0 tid=0x00007f0c8c2bc000 nid=0x4d55 waiting on condition [0x00007f0c4f6e6000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e4f4cf0> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-3" #12 prio=5 os_prio=0 tid=0x00007f0c8c2ba000 nid=0x4d54 waiting on condition [0x00007f0c4f7e7000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e40abb8> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-2" #11 prio=5 os_prio=0 tid=0x00007f0c8c2b8800 nid=0x4d53 waiting on condition [0x00007f0c4f8e8000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000775518738> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-1" #10 prio=5 os_prio=0 tid=0x00007f0c8c2b5800 nid=0x4d52 waiting on condition [0x00007f0c4f9e9000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076e486ab0> (a java.util.concurrent.Phaser$QNode)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.Phaser$QNode.block(Phaser.java:1140)
    at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323)
    at java.util.concurrent.Phaser.internalAwaitAdvance(Phaser.java:1067)
    at java.util.concurrent.Phaser.arriveAndAwaitAdvance(Phaser.java:690)
    at Ant.call(Ant.java:77)
    at Ant.call(Ant.java:10)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007f0c8c200800 nid=0x4d50 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=0 tid=0x00007f0c8c1fd800 nid=0x4d4f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=0 tid=0x00007f0c8c1f8800 nid=0x4d4e waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=0 tid=0x00007f0c8c1f7800 nid=0x4d4d waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=0 tid=0x00007f0c8c1fb000 nid=0x4d4c runnable [0x00007f0c781b4000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    - locked <0x000000077550ecb0> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    - locked <0x000000077550ecb0> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f0c8c181000 nid=0x4d49 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f0c8c14d800 nid=0x4d42 in Object.wait() [0x00007f0c78564000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000775500d08> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x0000000775500d08> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f0c8c149000 nid=0x4d41 in Object.wait() [0x00007f0c78665000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000775500d48> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    - locked <0x0000000775500d48> (a java.lang.ref.Reference$Lock)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"main" #1 prio=5 os_prio=0 tid=0x00007f0c8c00c800 nid=0x4d35 waiting on condition [0x00007f0c91f77000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076dd5e268> (a java.util.concurrent.FutureTask)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
    at java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at java.util.concurrent.AbstractExecutorService.invokeAll(AbstractExecutorService.java:244)
    at ConcurrentACS.loop(ConcurrentACS.java:138)
    at ConcurrentACS.compute(ConcurrentACS.java:165)
    at ConcurrentACS.main(ConcurrentACS.java:192)

"VM Thread" os_prio=0 tid=0x00007f0c8c141800 nid=0x4d3f runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f0c8c022000 nid=0x4d37 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f0c8c024000 nid=0x4d38 runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f0c8c025800 nid=0x4d39 runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f0c8c027800 nid=0x4d3a runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007f0c8c205800 nid=0x4d51 waiting on condition 

JNI global references: 272

is it possible for ConcurrentHashMap to hang? ConcurrentHashMap可以挂起吗?

The short answer is no if by "hang" you mean some sort of program loop or deadlock. 简短的回答是不,如果“挂起”你的意思是某种程序循环或死锁。 If you are implying that you have discovered a race condition (bug) in that code that would cause it to hang during normal JVM and system execution then I seriously doubt it. 如果你暗示你在该代码中发现了一个竞争条件(bug)会导致它在正常的JVM和系统执行期间挂起,那么我非常怀疑它。

I suspect that there is something else going on and just because you are using a CHM in the version that is hanging shouldn't imply that the class has a bug. 我怀疑还有其他事情发生,只是因为你在悬挂的版本中使用CHM并不意味着该类有一个bug。 I would use stack dumps or a profiler to show that the code is locked on a CHM line before I'd cast any blame that way. 我会使用堆栈转储或分析器来显示代码在CHM行上被锁定,然后我就会抛出任何责任。

Is it possible to be calling CHM at some large number of times per second so that the performance of your program suffers because of it? 是否有可能每秒多次调用CHM,以便程序的性能因此受到影响? Sure. 当然。 But it wouldn't hang in that it is stuck or deadlocked. 但它不会因为卡住或陷入僵局而陷入困境。

My CPU usage will gradually go up for ~6 seconds, and then it will go down to ~10% after peaked at ~100%. 我的CPU使用率将逐渐上升约6秒,然后在达到~100%达到峰值后下降到~10%。 I have plenty of unused memory left. 我还有很多未使用的内存。 (Does this look like deadlock?) (这看起来像僵局吗?)

Your now posted stack trace shows that no threads are locked in CHM code so it doesn't look to be the problem. 您现在发布的堆栈跟踪显示CHM代码中没有锁定任何线程,因此它看起来不是问题。 The performance curve you are talking about seems to be happening because of the fork/join thread-pool that you are using initially starts X threads but then some of them finish their tasks and exit. 您正在讨论的性能曲线似乎正在发生,因为您使用的fork / join线程池最初启动X线程,但随后其中一些完成了他们的任务并退出。 This is to be expected. 这是可以预料的。 It has nothing to do with the CHM. 它与CHM无关。

 if(maxIndices.containsKey(hash)) { return maxIndices.get(hash); 

Just a quick comment. 快速评论一下。 This code makes 2 calls to the CHM instead of something like: 此代码对CHM进行2次调用,而不是像:

Integer maxIndex = maxIndices.get(hash);
if (maxIndex != null) {
   return maxIndex;
}
...

But that's just inefficient and wouldn't cause a bug. 但这只是低效率,不会导致错误。 Also, it is important to recognize that race conditions in your code means that multiple threads might get a null for the index and calculate the index value. 此外,重要的是要认识到代码中的竞争条件意味着多个线程可能会为索引获取null并计算索引值。 But also this is not a bug which would cause a "hang". 但这也不是导致“挂起”的错误。

The first version isn't thread safe cause your check-than-act sequence isn't atomic. 第一个版本不是线程安全的,因为check-than-act序列不是原子序列。 Try to use this implementation: 尝试使用此实现:

  private final Map<Integer, Integer> maxIndices = new ConcurrentHashMap<>();

  int getMaxIndex(final double[] arr) {
    // make sure the content of the arr can't be modified concurrently
    // otherwise create a copy of the array in this method
    int hash = Arrays.hashCode(arr);
    return maxIndices.computeIfAbsent(hash,
        key -> IntStream.range(0, arr.length).reduce((a, b) -> arr[a] < arr[b] ? b : a).orElse(-1));
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ReentrantReadWriteLock 在 ConcurrentHashMap::compute() 中使用时挂起 - ReentrantReadWriteLock hang when used within ConcurrentHashMap::compute() ConcurrentHashMap是否可能“死锁”? - Is it possible for ConcurrentHashMap to “deadlock”? ConcurrentHashMap 等待键可能吗? - ConcurrentHashMap wait for key possible? 在这种情况下,是否有可能与 ConcurrentHashMap 陷入僵局? - Is it possible to get a deadlock with ConcurrentHashMap in this circumstance? 是否有可能使用 ConcurrentHashMap 与两个线程 lockRoot 发生死锁 - Is it possible to get a deadlock with ConcurrentHashMap with two threads lockRoot 是否可以将ConcurrentHashmap计算与java 7源代码级别一起使用? - Is it possible to use ConcurrentHashmap compute with java 7 source level? ConcurrentHashMap中是否可以有超过32个锁 - Is it possible to have more than 32 locks in ConcurrentHashMap 是否可以在不创建新对象的情况下迭代 ConcurrentHashMap? - Is it possible to iterate a ConcurrentHashMap without creating new objects? 是否可以允许比ConcurrentHashMap中的并发级别更多的线程数? - Is it possible to allow more number of threads than concurrency level in ConcurrentHashMap? Java中的ConcurrentHashMap中,锁的数量是否可能大于存储桶的数量? - Is it possible to have number of locks greater than number of buckets in ConcurrentHashMap in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM