Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8143380

Parallel stream can deadlock when called from static initializer

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 8u65, 9
    • core-libs

      FULL PRODUCT VERSION :
      $ /opt/java/jdk1.8.0_65/bin/java -version
      java version "1.8.0_65"
      Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
      Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      $ uname -a
      Linux jxc1 2.6.32-431.17.1.el6.x86_64 #1 SMP Wed May 7 23:32:49 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

      $ cat /etc/redhat-release
      CentOS release 6.5 (Final)



      A DESCRIPTION OF THE PROBLEM :
      Arrays.asList(..).parellelStream() will deadlock when called in <clinit> if the array length is 1024+. Instances of ArrayList have similar issues.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Inside the static initializer for a class, create a new Object[1024] and pass it to Arrays.asList(..). With the resulting list execute a .parallelStream().allMatch(..) with a lambda expression checking to see all elements are null. The resulting <clinit> will deadlock every time.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Code should execute and not dead-lock.
      ACTUAL -
      Always deadlocks after printing "start parallel n = 1024".

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      2015-11-19 21:21:21
      Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.65-b01 mixed mode):

      "ForkJoinPool.commonPool-worker-6" #15 daemon prio=5 os_prio=0 tid=0x00002ba600002800 nid=0x5e68 in Object.wait() [0x00002ba6180fe000]
         java.lang.Thread.State: RUNNABLE
              at Test$$Lambda$3/245257410.test(Unknown Source)
              at java.util.stream.MatchOps$1MatchSink.accept(MatchOps.java:90)
              at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
              at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
              at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
              at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
              at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
              at java.util.stream.MatchOps$MatchTask.doLeaf(MatchOps.java:306)
              at java.util.stream.MatchOps$MatchTask.doLeaf(MatchOps.java:277)
              at java.util.stream.AbstractShortCircuitTask.compute(AbstractShortCircuitTask.java:115)
              at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
              at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
              at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

      "ForkJoinPool.commonPool-worker-7" #16 daemon prio=5 os_prio=0 tid=0x00002ba604002800 nid=0x5e67 waiting on condition [0x00002ba5d7c08000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x000000076d448508> (a java.util.concurrent.ForkJoinPool)
              at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

      "ForkJoinPool.commonPool-worker-5" #14 daemon prio=5 os_prio=0 tid=0x00002ba57819f000 nid=0x5e66 in Object.wait() [0x00002ba5d7b07000]
         java.lang.Thread.State: RUNNABLE
              at Test$$Lambda$3/245257410.test(Unknown Source)
              at java.util.stream.MatchOps$1MatchSink.accept(MatchOps.java:90)
              at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
              at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
              at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
              at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
              at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
              at java.util.stream.MatchOps$MatchTask.doLeaf(MatchOps.java:306)
              at java.util.stream.MatchOps$MatchTask.doLeaf(MatchOps.java:277)
              at java.util.stream.AbstractShortCircuitTask.compute(AbstractShortCircuitTask.java:115)
              at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
              at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
              at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

      "ForkJoinPool.commonPool-worker-4" #13 daemon prio=5 os_prio=0 tid=0x00002ba604001000 nid=0x5e65 waiting on condition [0x00002ba5d7a06000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x000000076d448508> (a java.util.concurrent.ForkJoinPool)
              at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

      "ForkJoinPool.commonPool-worker-3" #12 daemon prio=5 os_prio=0 tid=0x00002ba600001000 nid=0x5e64 waiting on condition [0x00002ba5d7905000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x000000076d448508> (a java.util.concurrent.ForkJoinPool)
              at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

      "ForkJoinPool.commonPool-worker-2" #11 daemon prio=5 os_prio=0 tid=0x00002ba57819d800 nid=0x5e63 waiting on condition [0x00002ba5d7804000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x000000076d448508> (a java.util.concurrent.ForkJoinPool)
              at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

      "ForkJoinPool.commonPool-worker-1" #10 daemon prio=5 os_prio=0 tid=0x00002ba57819c000 nid=0x5e62 waiting on condition [0x00002ba5d7703000]
         java.lang.Thread.State: WAITING (parking)
              at sun.misc.Unsafe.park(Native Method)
              - parking to wait for <0x000000076d448508> (a java.util.concurrent.ForkJoinPool)
              at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

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

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

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

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

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

      "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00002ba5780b0800 nid=0x5e5b waiting on condition [0x0000000000000000]
         java.lang.Thread.State: RUNNABLE

      "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00002ba578086000 nid=0x5e5a in Object.wait() [0x00002ba5d6efb000]
         java.lang.Thread.State: WAITING (on object monitor)
              at java.lang.Object.wait(Native Method)
              - waiting on <0x000000076d0070b8> (a java.lang.ref.ReferenceQueue$Lock)
              at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
              - locked <0x000000076d0070b8> (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=0x00002ba578084000 nid=0x5e59 in Object.wait() [0x00002ba5d6dfa000]
         java.lang.Thread.State: WAITING (on object monitor)
              at java.lang.Object.wait(Native Method)
              - waiting on <0x000000076d006af8> (a java.lang.ref.Reference$Lock)
              at java.lang.Object.wait(Object.java:502)
              at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
              - locked <0x000000076d006af8> (a java.lang.ref.Reference$Lock)

      "main" #1 prio=5 os_prio=0 tid=0x00002ba578009000 nid=0x5e4f in Object.wait() [0x00002ba576c7c000]
         java.lang.Thread.State: WAITING (on object monitor)
              at java.lang.Object.wait(Native Method)
              - waiting on <0x000000076d459548> (a java.util.stream.MatchOps$MatchTask)
              at java.util.concurrent.ForkJoinTask.externalAwaitDone(ForkJoinTask.java:334)
              - locked <0x000000076d459548> (a java.util.stream.MatchOps$MatchTask)
              at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:405)
              at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
              at java.util.stream.MatchOps$MatchOp.evaluateParallel(MatchOps.java:242)
              at java.util.stream.MatchOps$MatchOp.evaluateParallel(MatchOps.java:196)
              at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
              at java.util.stream.ReferencePipeline.allMatch(ReferencePipeline.java:454)
              at Test.<clinit>(Test.java:15)

      "VM Thread" os_prio=0 tid=0x00002ba57807f000 nid=0x5e58 runnable

      "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00002ba57801e000 nid=0x5e50 runnable

      "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00002ba578020000 nid=0x5e51 runnable

      "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00002ba578021800 nid=0x5e52 runnable

      "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00002ba578023800 nid=0x5e53 runnable

      "GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00002ba578025000 nid=0x5e54 runnable

      "GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00002ba578027000 nid=0x5e55 runnable

      "GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00002ba578028800 nid=0x5e56 runnable

      "GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00002ba57802a800 nid=0x5e57 runnable

      "VM Periodic Task Thread" os_prio=0 tid=0x00002ba5780e4000 nid=0x5e61 waiting on condition

      JNI global references: 318

      Heap
       PSYoungGen total 74752K, used 14416K [0x000000076d000000, 0x0000000772300000, 0x00000007c0000000)
        eden space 64512K, 22% used [0x000000076d000000,0x000000076de143b8,0x0000000770f00000)
        from space 10240K, 0% used [0x0000000771900000,0x0000000771900000,0x0000000772300000)
        to space 10240K, 0% used [0x0000000770f00000,0x0000000770f00000,0x0000000771900000)
       ParOldGen total 171008K, used 0K [0x00000006c7000000, 0x00000006d1700000, 0x000000076d000000)
        object space 171008K, 0% used [0x00000006c7000000,0x00000006c7000000,0x00000006d1700000)
       Metaspace used 3730K, capacity 4650K, committed 4864K, reserved 1056768K
        class space used 421K, capacity 462K, committed 512K, reserved 1048576K



      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.*;

      public class Test {
        static {
          for (int n = 16; n <= 0x1000000 ; n<<=1) {
            Object[] array = new Object[n];
            List<?> list = Arrays.asList(array);

            System.out.println("start sequential n = "+n);
            list.stream().allMatch((v) -> (v == null));
            System.out.println("done sequential n = "+n);
            System.out.println("");
            
            System.out.println("start parallel n = "+n);
            list.parallelStream().allMatch((v) -> (v == null));
            System.out.println("done parallel n = "+n);
            System.out.println("");
          }
        }

        public static void main (String... args) throws Exception {
          // done
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Changing the line:
            List<Object> list = Arrays.asList(array);

      To:
            List<Object> list = new ArrayList<>();
            for (int i = 0; i < n; i++) {
              list.add(i);
            }

      Seems to solve the problem.

      However changing the line:
            List<Object> list = Arrays.asList(array);

      To:
            List<?> list = new ArrayList(Arrays.asList(array));

      Will *not* solve the problem -- but it does vary the number of iterations before a deadlock occurs.

      ===========================

      Additionally using .stream() rather than .parallelStream() seems to fix the issue; though this results in sequential execution which can be slower.

            smarks Stuart Marks
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: