Java 8流 – stackoverflow异常

运行以下代码示例以:
“线程中的异常”主要“ java.lang.StackOverflowError”
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class TestStream {

    public static void main(String[] args) {
        Stream<String> reducedStream = IntStream.range(0,15000)
            .mapToObj(Abc::new)
            .reduce(
                Stream.of("Test"),(str,abc) -> abc.process(str),(a,b) -> {throw new IllegalStateException();}
        );
        System.out.println(reducedStream.findFirst().get());
    }

    private static class Abc { 
        public Abc(int id) {
        }

        public Stream<String> process(Stream<String> batch) {
            return batch.map(this::donothing);
        }

        private String donothing(String test) {
            return test;
        }
    }
}

究竟是什么导致了这个问题?这段代码的哪一部分是递归的,为什么?

解决方法

你的代码没有递归循环.您可以使用较小的数字测试IntStream范围(即1或100).在你的情况下,这是导致问题的实际堆栈大小限制.正如在一些评论中指出的,它的流程是进程.

流上的每个调用都会在原始文件周围创建一个新的包装流. ‘findFirst()’方法向前一个流请求元素,这些元素又要求先前的流元素.由于流不是真正的容器,而只是对结果元素的指针.

包装爆炸发生在reduce方法的“累加器”(str,abc) – > abc.process(STR)”.该方法的实现在先前操作的结果(str)上创建一个新的流包装器,进入下一个迭代,在结果(result(str))上创建一个新的包装器).所以累积机制是一个包装(递归)而不是一个appender(迭代)之一.因此,创建一个实际(扁平化)结果的新流,而不是参考潜在的结果将会阻止爆炸,即

public Stream<String> process(Stream<String> batch) {
        return Stream.of(batch.map(this::donothing).collect(Collectors.joining()));
    }

这个方法只是一个例子,因为你的原始例子没有任何意义,因为它什么都不做,而且这个例子也不是.它只是一个例证.它基本上将由map方法返回的流的元素平坦化为单个字符串,并在此具体字符串上创建新流,而不是在流本身上,这与您的原始代码的区别.

您可以使用定义每个线程堆栈大小的“-Xss”参数调整堆栈大小.认值取决于平台,另请参阅此问题‘What is the maximum depth of the java call stack?’但是,在增加时请小心,此设置适用于所有线程.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


应用场景 C端用户提交工单、工单创建完成之后、会发布一条工单创建完成的消息事件(异步消息)、MQ消费者收到消息之后、会通知各处理器处理该消息、各处理器处理完后都会发布一条将该工单写入搜索引擎的消息、最终该工单出现在搜索引擎、被工单处理人检索和处理。 事故异常体现 1、异常体现 从工单的流转记录发现、
线程类,设置有一个公共资源 package cn.org.chris.concurrent; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Descrip
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量
Java 9中JShell中的不同启动脚本是什么?
使用Java的位填充错误检测技术
java中string是什么
如何使用Java中的JSON-lib API将Map转换为JSON对象?
Java菜单驱动程序以检查数字类型
使用Junit的Maven项目 - 检查银行账号
JAVA编程基础
在Java中使用throw、catch和instanceof来处理异常
在Java中,将数组分割为基于给定查询的子数组后,找到子数组的最大子数组和
如何在Java中从给定的字符串中删除HTML标签?
在PHP中,IntlChar getBlockCode()函数的翻译如下:
如何在Android中实现按下返回键再次退出的功能?
如何使用Java中的流式API解析JSON字符串?
Java中的模式类