• stream流引发的问题


        
         SearchHit[] searchHits1 = searchHits.get();

         //方式一
    for (int i = 0; i < searchHits1.length; i++) {
    Map<String, Object> source = searchHits1[i].getSource();
    list.add(source);
    }
         //方式二
    if (searchHits.isPresent()) {
    Arrays.asList(searchHits.get()).parallelStream().forEach(InternalSearchHit -> list.add(InternalSearchHit.getSource()));
    }

    代码的逻辑是从es库中查出指定的数据,然后存放到list集合中,返回页面或者进行其他处理;这里遇到的问题就是,在方式二操作的时候,list中会出现空数据,如下图:

    存在空数据的情况,所以就会造成各种想不到的bug,唉,头疼啊;

    换成方式一显示正常;

    为啥?

    究其原因:我仔细找找。。。

    找到了,是流的原因,换成以下代码,就可以了:

            if (searchHits.isPresent()) {
                Arrays.asList(searchHits.get()).stream().forEach(InternalSearchHit -> list.add(InternalSearchHit.getSource()));
            }

    这里就要说说流的区别了:

    stream()和parallelStream()的区别:简单的说就是一个是单管道,另个一个是多管道;因为是多管道,就会涉及到线程安全问题;遍历耗时前者是后者的将近一半

    引用看到的一篇文章部分内容:https://blog.csdn.net/zhao1299002788/article/details/85004434

    在使用stream.foreach时这个遍历没有线程安全问题,但是使用parallelStream就会有线程安全问题,所有在parallelStream里面使用的外部变量,比如集合一定要

    使用线程安全集合,不然就会引发多线程安全问题。在并行时,实际上是多个线程执行,这个时候还有个问题,就是当你在遍历中使用例如请求里面的数据时,就

    会报一个异常,这个异常就是多个线程执行,但是其他线程没有这个请求的数据,所以获取不到。这时解决办法是把需要的数据在遍历外面取到,再传递进去就可

    以解决。
    或者说,是外部的list不是线程安全的,导致了parallelStream()线不安全;

  • 相关阅读:
    k8s学习
    k8s学习
    k8s学习
    Linux 常用命令(持续补充)
    通过一个小故事,理解 HTTPS 工作原理
    Spring Cloud 微服务架构全链路实践
    Spring Cloud Eureka 使用 IP 地址进行服务注册
    RabbitMQ 消息顺序、消息幂等、消息重复、消息事务、集群
    Spring Boot 实现 RabbitMQ 延迟消费和延迟重试队列
    RabbitMQ 集群原理和完善
  • 原文地址:https://www.cnblogs.com/notchangeworld/p/11649464.html
Copyright © 2020-2023  润新知