当前位置: 首页 > 面试题库 >

流和parallelStream

邵研
2023-03-14
问题内容

我有这样的测试代码:

List<Integer> list = new ArrayList<>(1000000);

for(int i=0;i<1000000;i++){
    list.add(i);
}

List<String> values = new ArrayList<>(1000000);

list.stream().forEach(
    i->values.add(new Date().toString())
);

System.out.println(values.size());

运行此命令,我得到了正确的输出:1000000。

但是,如果我将更stream()改为parallelStream(),则如下所示:

 list.parallelStream().forEach(
    i->values.add(new Date().toString())
 );

我得到了一个随机输出,例如:920821。

怎么了?


问题答案:

An
ArrayList未同步。没有定义尝试同时向其添加元素。来自forEach

对于并行流管道,此操作不能保证尊重流的遇到顺序,因为这样做会牺牲并行性的好处。 对于任何给定的元素,可以在库选择的任何时间和线程中执行该操作

在第二个示例中,最终导致多个线程同时调用add数组列表,并且ArrayList文档显示:

请注意,此实现未同步。如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改列表,则必须在外部进行同步。

错误的解决方案

如果你改变了使用的ArrayList一个Vector,你会得到正确的结果,因为这个列表实现同步。它的Javadoc说:

与新的集合实现不同,它Vector是同步的。

但是,请不要使用它!此外,由于显式同步,它最终可能会变慢。

正确的方法

明确地避免这种情况的是,Stream API
使用该方法提供了可变的简化范例collect。下列

List<String> values = list.stream().map(i -> "foo").collect(Collectors.toList());

无论是否并行运行,都将始终提供正确的结果。Stream管道在内部处理并发,并确保在并行流的collect操作中使用非并发收集器是安全的。Collectors.toList()是一个内置的收集器,它将一个Stream的元素累积到一个列表中。



 类似资料:
  • 问题内容: 请解释什么是字节流和字符流。这些到底是什么意思?Microsoft Word文档是面向字节还是面向字符? 谢谢 问题答案: 流是顺序访问文件的一种方式。字节流逐字节访问文件。字节流适用于任何类型的文件,但不适用于文本文件。例如,如果文件使用unicode编码,并且一个字符用两个字节表示,则字节流将分别处理这些字节,您需要自己进行转换。 字符流将逐字符读取文件。必须为字符流提供文件的编码

  • 主要内容:C++输入流和输出流本教程一开始就提到,C++ 又可以称为“带类的 C”,即可以理解为 C++ 是 C 语言的基础上增加了面向对象(类和对象)。在此基础上,学过 C 语言的读者应该知道,它有一整套完成数据读写(I/O)的解决方案: 使用 scanf()、gets() 等函数从键盘读取数据,使用 printf()、puts() 等函数向屏幕上输出数据; 使用 fscanf()、fgets() 等函数读取文件中的数据,使

  • 本文向大家介绍浅析Java.IO输入输出流 过滤流 buffer流和data流,包括了浅析Java.IO输入输出流 过滤流 buffer流和data流的使用技巧和注意事项,需要的朋友参考一下 java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题。 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流。 问题引入: 缓冲流为什么比普通的文件字节流效率高? 不带

  • 问题内容: 我正在寻找如何在Meteor Up Docker上安装Graphicsmagick。 我找到了这个解决方案docker中的Accessbinaries,但是我无法工作,我应该将这些行放在哪里? 那是我的: 问题答案: 每次您重新启动容器时都要重新安装graphicsmagick软件包,这看起来像是我不想做的黑客。 如果您已经在修改启动脚本,则不妨使用Dockerfile: 然后修改模板

  • 我正在尝试使用MediaExtractor/MediaCodec播放mp3流。由于延迟和长缓冲区大小,MediaPlayer是不可能的。 我找到的唯一示例代码是:http://dpsm.wordpress.com/category/android/ 代码示例只是局部的(?)并使用文件而不是流。 我一直在尝试调整这个例子来播放音频流,但我无法理解这应该是如何工作的。Android留档一如既往没有帮助

  • 我对使用rxjava进行反应性编程是新手,在经历了更简单的示例之后,我现在试图弄清楚如何使用连续流。下面这个例子的问题是,在我接受了3个元素后,程序不会终止。我的假设是,我不知何故需要取消订阅我的可观察的,但我不完全掌握如何终止while循环并使程序退出。 我遇到了下面的RxJava帖子--终止无限流,但我仍然不知道我遗漏了什么。