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

Parallel, infinite Stream with limit, does not obey limit & hangs the program

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 8u60
    • core-libs

      FULL PRODUCT 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 :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      When applying a limit to an infinite, parallel Stream, the limit is sometimes not enforced. Because of this, the program hangs (since it keeps processing the infinite Stream).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the executable test case.

      Note that, from my experience, the number 2868 is the smallest number with which the program hangs.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      A single line of output:
      28680
      ACTUAL -
      No output: the program hangs

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.Iterator;
      import java.util.List;
      import java.util.Spliterator;
      import java.util.Spliterators;
      import java.util.concurrent.atomic.AtomicInteger;
      import java.util.stream.Stream;
      import java.util.stream.StreamSupport;

      public class TestCase {

      public static void main(String[] args) {
      List<Integer> numbers = Collections.nCopies(2868, 0);
      System.out.println(cycle(numbers, 10).count());
      }

      public static <T> Stream<T> cycle(List<T> list, int nbIterations) {
      return StreamSupport.stream(Spliterators.spliterator(new Iterator<T>() {

      private final List<T> copy = new ArrayList<>(list);
      private final AtomicInteger position = new AtomicInteger();

      @Override
      public boolean hasNext() {
      return true;
      }

      @Override
      public T next() {
      return copy.get(position.getAndUpdate(n -> (n + 1) % copy.size()));
      }

      }, Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED), true).limit(list.size() * nbIterations);
      }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Make the stream sequential

            igerasim Ivan Gerasimov
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: