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

Parallel stream can deadlock when called from static initializer

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Not an Issue
    • Affects Version/s: 8u65, 9
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:

      Description

      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.

        Activity

        Hide
        psonal Pallavi Sonal added a comment - - edited
        Attached Test case was executed on
        JDK 8u66 - Fail
        JDK 8u72 -Fail
        JDK 9ea b85 - 1 out of every 5 run is successfully completed. The other 4 runs deadlock.
        In all the cases, the deadlock happens at different iterations.
        Sample outputs:
        ------------------------------------------------------------------------------
        D:\TestCases\src>java TestCollectionParallelStream (Successful run)
        start sequential n = 16
        done sequential n = 16

        start parallel n = 16
        done parallel n = 16

        start sequential n = 32
        done sequential n = 32

        start parallel n = 32
        done parallel n = 32

        start sequential n = 64
        done sequential n = 64

        start parallel n = 64
        done parallel n = 64

        start sequential n = 128
        done sequential n = 128

        start parallel n = 128
        done parallel n = 128

        start sequential n = 256
        done sequential n = 256

        start parallel n = 256
        done parallel n = 256

        start sequential n = 512
        done sequential n = 512

        start parallel n = 512
        done parallel n = 512

        start sequential n = 1024
        done sequential n = 1024

        start parallel n = 1024
        done parallel n = 1024

        start sequential n = 2048
        done sequential n = 2048

        start parallel n = 2048
        done parallel n = 2048

        start sequential n = 4096
        done sequential n = 4096

        start parallel n = 4096
        done parallel n = 4096

        start sequential n = 8192
        done sequential n = 8192

        start parallel n = 8192
        done parallel n = 8192

        start sequential n = 16384
        done sequential n = 16384

        start parallel n = 16384
        done parallel n = 16384

        start sequential n = 32768
        done sequential n = 32768

        start parallel n = 32768
        done parallel n = 32768

        start sequential n = 65536
        done sequential n = 65536

        start parallel n = 65536
        done parallel n = 65536

        start sequential n = 131072
        done sequential n = 131072

        start parallel n = 131072
        done parallel n = 131072

        start sequential n = 262144
        done sequential n = 262144

        start parallel n = 262144
        done parallel n = 262144

        start sequential n = 524288
        done sequential n = 524288

        start parallel n = 524288
        done parallel n = 524288

        start sequential n = 1048576
        done sequential n = 1048576

        start parallel n = 1048576
        done parallel n = 1048576

        start sequential n = 2097152
        done sequential n = 2097152

        start parallel n = 2097152
        done parallel n = 2097152

        start sequential n = 4194304
        done sequential n = 4194304

        start parallel n = 4194304
        done parallel n = 4194304

        start sequential n = 8388608
        done sequential n = 8388608

        start parallel n = 8388608
        done parallel n = 8388608

        start sequential n = 16777216
        done sequential n = 16777216

        start parallel n = 16777216
        done parallel n = 16777216
        -----------------------------------------------------------------------------------------------
        D:\TestCases\src>java TestCollectionParallelStream
        start sequential n = 16
        done sequential n = 16

        start parallel n = 16
        done parallel n = 16

        start sequential n = 32
        done sequential n = 32

        start parallel n = 32
        done parallel n = 32

        start sequential n = 64
        done sequential n = 64

        start parallel n = 64
        done parallel n = 64

        start sequential n = 128
        done sequential n = 128

        start parallel n = 128
        done parallel n = 128

        start sequential n = 256
        done sequential n = 256

        start parallel n = 256
        done parallel n = 256

        start sequential n = 512
        done sequential n = 512

        start parallel n = 512
        ------------------------------------------------------------------------------------------------
        D:\TestCases\src>java TestCollectionParallelStream
        start sequential n = 16
        done sequential n = 16

        start parallel n = 16
        done parallel n = 16

        start sequential n = 32
        done sequential n = 32

        start parallel n = 32
        done parallel n = 32

        start sequential n = 64
        done sequential n = 64

        start parallel n = 64
        done parallel n = 64

        start sequential n = 128
        done sequential n = 128

        start parallel n = 128
        done parallel n = 128

        start sequential n = 256
        done sequential n = 256

        start parallel n = 256
        done parallel n = 256

        start sequential n = 512
        done sequential n = 512

        start parallel n = 512
        done parallel n = 512

        start sequential n = 1024
        done sequential n = 1024

        start parallel n = 1024
        done parallel n = 1024

        start sequential n = 2048
        done sequential n = 2048

        start parallel n = 2048
        done parallel n = 2048

        start sequential n = 4096
        done sequential n = 4096

        start parallel n = 4096
        done parallel n = 4096

        start sequential n = 8192
        done sequential n = 8192

        start parallel n = 8192
        done parallel n = 8192

        start sequential n = 16384
        done sequential n = 16384

        start parallel n = 16384
        done parallel n = 16384

        start sequential n = 32768
        done sequential n = 32768

        start parallel n = 32768
        --------------------------------------------------------------------------------------------
        Moving across to dev-team for evaluation.
        Show
        psonal Pallavi Sonal added a comment - - edited Attached Test case was executed on JDK 8u66 - Fail JDK 8u72 -Fail JDK 9ea b85 - 1 out of every 5 run is successfully completed. The other 4 runs deadlock. In all the cases, the deadlock happens at different iterations. Sample outputs: ------------------------------------------------------------------------------ D:\TestCases\src>java TestCollectionParallelStream (Successful run) start sequential n = 16 done sequential n = 16 start parallel n = 16 done parallel n = 16 start sequential n = 32 done sequential n = 32 start parallel n = 32 done parallel n = 32 start sequential n = 64 done sequential n = 64 start parallel n = 64 done parallel n = 64 start sequential n = 128 done sequential n = 128 start parallel n = 128 done parallel n = 128 start sequential n = 256 done sequential n = 256 start parallel n = 256 done parallel n = 256 start sequential n = 512 done sequential n = 512 start parallel n = 512 done parallel n = 512 start sequential n = 1024 done sequential n = 1024 start parallel n = 1024 done parallel n = 1024 start sequential n = 2048 done sequential n = 2048 start parallel n = 2048 done parallel n = 2048 start sequential n = 4096 done sequential n = 4096 start parallel n = 4096 done parallel n = 4096 start sequential n = 8192 done sequential n = 8192 start parallel n = 8192 done parallel n = 8192 start sequential n = 16384 done sequential n = 16384 start parallel n = 16384 done parallel n = 16384 start sequential n = 32768 done sequential n = 32768 start parallel n = 32768 done parallel n = 32768 start sequential n = 65536 done sequential n = 65536 start parallel n = 65536 done parallel n = 65536 start sequential n = 131072 done sequential n = 131072 start parallel n = 131072 done parallel n = 131072 start sequential n = 262144 done sequential n = 262144 start parallel n = 262144 done parallel n = 262144 start sequential n = 524288 done sequential n = 524288 start parallel n = 524288 done parallel n = 524288 start sequential n = 1048576 done sequential n = 1048576 start parallel n = 1048576 done parallel n = 1048576 start sequential n = 2097152 done sequential n = 2097152 start parallel n = 2097152 done parallel n = 2097152 start sequential n = 4194304 done sequential n = 4194304 start parallel n = 4194304 done parallel n = 4194304 start sequential n = 8388608 done sequential n = 8388608 start parallel n = 8388608 done parallel n = 8388608 start sequential n = 16777216 done sequential n = 16777216 start parallel n = 16777216 done parallel n = 16777216 ----------------------------------------------------------------------------------------------- D:\TestCases\src>java TestCollectionParallelStream start sequential n = 16 done sequential n = 16 start parallel n = 16 done parallel n = 16 start sequential n = 32 done sequential n = 32 start parallel n = 32 done parallel n = 32 start sequential n = 64 done sequential n = 64 start parallel n = 64 done parallel n = 64 start sequential n = 128 done sequential n = 128 start parallel n = 128 done parallel n = 128 start sequential n = 256 done sequential n = 256 start parallel n = 256 done parallel n = 256 start sequential n = 512 done sequential n = 512 start parallel n = 512 ------------------------------------------------------------------------------------------------ D:\TestCases\src>java TestCollectionParallelStream start sequential n = 16 done sequential n = 16 start parallel n = 16 done parallel n = 16 start sequential n = 32 done sequential n = 32 start parallel n = 32 done parallel n = 32 start sequential n = 64 done sequential n = 64 start parallel n = 64 done parallel n = 64 start sequential n = 128 done sequential n = 128 start parallel n = 128 done parallel n = 128 start sequential n = 256 done sequential n = 256 start parallel n = 256 done parallel n = 256 start sequential n = 512 done sequential n = 512 start parallel n = 512 done parallel n = 512 start sequential n = 1024 done sequential n = 1024 start parallel n = 1024 done parallel n = 1024 start sequential n = 2048 done sequential n = 2048 start parallel n = 2048 done parallel n = 2048 start sequential n = 4096 done sequential n = 4096 start parallel n = 4096 done parallel n = 4096 start sequential n = 8192 done sequential n = 8192 start parallel n = 8192 done parallel n = 8192 start sequential n = 16384 done sequential n = 16384 start parallel n = 16384 done parallel n = 16384 start sequential n = 32768 done sequential n = 32768 start parallel n = 32768 -------------------------------------------------------------------------------------------- Moving across to dev-team for evaluation.
        Hide
        smarks Stuart Marks added a comment -
        This is a class initialization deadlock. The test program's main thread executes the class static initializer, which sets the initialization in-progress flag for the class; this flag remains set until the static initializer completes. The static initializer executes a parallel stream, which causes lambda expressions to be evaluated in other threads. Those threads block waiting for the class to complete initialization. However, the main thread is blocked waiting for the parallel tasks to complete, resulting in deadlock.

        The test program should be changed to move the parallel stream logic outside of the class static initializer. Closing as Not an Issue.
        Show
        smarks Stuart Marks added a comment - This is a class initialization deadlock. The test program's main thread executes the class static initializer, which sets the initialization in-progress flag for the class; this flag remains set until the static initializer completes. The static initializer executes a parallel stream, which causes lambda expressions to be evaluated in other threads. Those threads block waiting for the class to complete initialization. However, the main thread is blocked waiting for the parallel tasks to complete, resulting in deadlock. The test program should be changed to move the parallel stream logic outside of the class static initializer. Closing as Not an Issue.
        Hide
        smarks Stuart Marks added a comment -
        An interesting variation on this is as follows. Code with this line:

            list.parallelStream().allMatch(v -> v == null);

        will deadlock, but code with this line:

            list.parallelStream().allMatch(Objects::isNull);

        might not. The reason is that the first line has a lambda expression, which gets compiled into a static method in this class. When another thread invokes the lambda, it results in a call to that static method, which will block awaiting class initialization. The second line has a method reference, which doesn't produce a static method on this class. When it's invoked, it calls the isNull() method on the java.util.Objects class directly, avoiding blocking on class initialization.

        This is just a small wrinkle, however. In general it is quite dangerous to interact with multiple threads during from within a static initializer, so this should be avoided if possible.
        Show
        smarks Stuart Marks added a comment - An interesting variation on this is as follows. Code with this line:     list.parallelStream().allMatch(v -> v == null); will deadlock, but code with this line:     list.parallelStream().allMatch(Objects::isNull); might not. The reason is that the first line has a lambda expression, which gets compiled into a static method in this class. When another thread invokes the lambda, it results in a call to that static method, which will block awaiting class initialization. The second line has a method reference, which doesn't produce a static method on this class. When it's invoked, it calls the isNull() method on the java.util.Objects class directly, avoiding blocking on class initialization. This is just a small wrinkle, however. In general it is quite dangerous to interact with multiple threads during from within a static initializer, so this should be avoided if possible.

          People

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

            Dates

            • Created:
              Updated:
              Resolved: