Java 8 Streams – Timeout?

I want to loop over a huge array and do a complicated set of instructions that takes a long time. However, if more than 30 seconds have passed, I want it to give up.

ex.

final long start = System.currentTimeMillis();
myDataStructure.stream()
    .while(() -> System.currentTimeMillis() <= start + 30000)
    .forEach(e ->
    {
      ...
    });

I want to avoid just saying return inside the forEach call if a certain condition is met.

Since Stream forEach doesn’t have break, I think you can create Custom Exception for this to break the loop:

myDataStructure.stream()
    .forEach(e ->
    {
      if (System.currentTimeMillis() <= start + 30000) {
          throw new MyTimeOutException()
      }
    });

and you can catch this Exception for catch this.

If iterating the stream or array in this case is cheap compared to actually executing the operation than just use a predicate and filter whether time is over or not.

final long end = System.nanoTime() + TimeUnit.SECONDS.toNanos(30L);
myDataStructure.stream()
    .filter(e -> System.nanoTime() <= end)
    .forEach(e ->
    {
      ...
    });

Question is if you need to know which elements have been processed or not. With the above you have to inspect whether a side effect took place for a specific element afterwards.

You can use the fact that .allMatch() is a short-circuiting operator to terminate the stream:

final long start = System.currentTimeMillis();
myDataStructure.stream()
    .allMatch(e ->
    {
      // your task here
        return System.currentTimeMillis() <= start + 30000;
    });

I would create a custom pool for that, something like:

ForkJoinPool forkJoinPool = new ForkJoinPool(1);
    try {
        forkJoinPool.submit(() ->
        IntStream.range(1, 1_000_000).filter(x -> x > 2).boxed().collect(Collectors.toList()))
                .get(30, TimeUnit.MILLISECONDS);
    } catch (TimeoutException e) {
        // job not done in your interval
    }

As what the comments said under the OP, takeWhile/dropWhile are missed in Java 8 (will be added in Java 9). There is no any reason to try to implement the logic by exception or other codes because the code just looks so ugly and total nonscenes even it’s just for practice. I think using 3rd party library is a much, much better solution, for example StreamEx

StreamEx(source).takeWhile(() -> System.currentTimeMillis() <= start + 30000)
                .forEach(e -> { ... });