这是一篇译文,原文链接见这里

本文同时发表在ImportNew上,转载请注明出处。

我很擅长同时处理多项任务。就算是在写这篇博客的此刻,我仍然在为昨天在聚会上发表了一个让大家都感到诧异的评论而觉得尴尬。好吧,好消息是我并不孤单——Java 8在多任务处理方面同样很优秀。让我们来看看它是怎么做的。

在Java 8引入的新功能中,有很重要的一项是并行数组处理。这项新功能使得我们能够使用可以利用多核体系结构的Lambda表达式来对对数组的元素进行排序,过滤和分组。这里的重点是,Java程序员只需要非常少的工作就可以立刻使程序的性能获得提升。非常酷。

问题来了。这项新功能有多快?我应该什么时候使用它?好吧,答案有点让人沮丧——这依赖于具体的情况。要知道依赖什么情况吗?请继续阅读。

新的API

Java8的新并行操作API十分灵活。让我们一起看几个我们要用来做测试的例子。

1. 使用多核对数组进行排序

Arrays.parallelSort(numbers);

2. 根据特定的条件(比如:素数和非素数)对数组进行分组

Map<Boolean, List<Integer>> groupByPrimary = numbers
.parallelStream().collect(Collectors.groupingBy(s -> Utility.isPrime(s)));

3. 对数组进行过滤

Integer[]  prims = numbers.parallelStream().filter(s -> Utility.isPrime(s))
.toArray();

跟自己写多线程程序来实现相同的功能比较,生产力提高太多了!在这个新的体系中,我个人最喜欢的是一个叫Spliterator的新概念,将一个集合分成多个块,并行处理这多个块并将处理结果汇合到一起。就像它的哥哥iterator,它也被用来遍历一个集合的元素,只不过它更加灵活,允许你编写检查和分离集合的自定义行为,并在遍历时直接插入。

它的性能如何?

为了测试这些并行操作API的性能, 我在两种情况(低竞争和高竞争)下进行了实验。原因是单独运行一个多核算法,往往会有好的性能,但在真实的服务器环境中运行,情况就完全不同了。真实环境中往往有大量的线程在竞争宝贵的CPU时间片以处理消息或用户请求,由于竞争的存在,程序的性能就降低了。所以我进行了接下来的测试。我首先随机生成了长度为100K的整数数组,这些整数的取值在0到1百万之间。然后我分别使用传统的顺序方法和新的Java 8的并行API对这个数组进行了排序,分组和过滤。结果并不使人惊讶。

  • 快速排序快了4.7
  • 分组快了5
  • 过滤快了5.5

这可以说明java 8的并行API具有非常好的性能吗?很不幸,不能。



*测试结果与运行了100次的附加测试结果一致。

*测试机器为MBP,i7四核。

在有负载的情况下会发生什么呢?

目前为止新API的性能表现非常出色,原因是线程之间对CPU的时间片的竞争非常少。这是理想的环境,但不行的是,理想环境往往不会出现在现实环境中。为了模拟真实的环境,我建立了第二个测试。这次测试使用跟第一次相同的算法,但测试任务在十个并发线程上执行,以模拟处在压力环境中的服务器同时处理十个请求的情况。这十个请求使用传统的顺利处理方法或Java 8的新API处理。

测试结果

  • 排序现在只快了20%
  • 过滤现在只快了20%
  • 分组现在慢了15%

更高的规模和竞争水平很可能使这些数字进一步下降。原因是在一个多线程的环境中添加线程并不一定能帮助你提高计算效率,是计算机的CPU个数决定了计算效率,而不是线程个数。

结论

虽然这些都是非常强大和易于使用的API,但它们不是银弹。我们仍然需要花费精力去判断何时应该使用它们。如果你事先知道你会做多个处理并行操作,那么考虑使用排队架构,并使并发操作数和你的处理器数量相匹配可能是一>个好主意。这里的难点在于运行时性能将依赖于实际的硬件体系结构和服务器所处的压力情况。你可能只有在压力测试或者生产环境中才能看到代码的运行时性能,使之成为一个“易编码,难调试”的经典案例。

Java 8的新并行API - 魅力与炫目背后的更多相关文章

  1. Java笔记 - 线程与并行API

    一.线程简介 1.线程与进程 每个进程都具有独立的代码和数据空间,进程间的切换会有较大的开销.线程是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开 ...

  2. java JDK8 学习笔记——第11章 线程和并行API

    第11章 线程与并行API 11.1 线程 11.1.1 线程 在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run( ...

  3. Java 9中新的货币API

    译文出处: Java译站   原文出处:Michael Scharhag JSR 354定义了一套新的Java货币API,计划会在Java 9中正式引入.本文中我们将来看一下它的参考实现:JavaMo ...

  4. Java 8 (11) 新的日期和时间API

    在Java 1.0中,对日期和时间的支持只能依赖java.util.Date类.这个类只能以毫秒的精度表示时间.这个类还有很多糟糕的问题,比如年份的起始选择是1900年,月份的起始从0开始.这意味着你 ...

  5. java 8中新的日期和时间API

    java 8中新的日期和时间API 使用LocalDate和LocalTime LocalDate的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息.另外,它也不附带任何与时区相关的信 ...

  6. [转] Java 8的新特性

    简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的例子 ...

  7. Java 8 中的 Streams API 详解

    为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...

  8. Java 8的新特性—终极版

    作者:杜琪[译] 原文链接:http://www.jianshu.com/p/5b800057f2d8 1. 简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本 ...

  9. Java 8 的新特性和改进总览

    这篇文章是对Java 8中即将到来的改进做一个面向开发者的综合性的总结,JDK的这一特性将会在2013年9月份发布. 在写这篇文章的时候,Java 8的开发工作仍然在紧张有序的进行中,语言特新和API ...

随机推荐

  1. C#:WebBrowser控件设置代理IP访问网站【附源码】

    软件截图 源码下载 http://download.csdn.net/detail/php_fly/8041731  

  2. mysql 创建用户并赋予权限

    mysql> create user 'zhangsan'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.00 ...

  3. 用于主题检测的临时日志(b2d5c7b3-e3f6-4b0f-bfa4-a08e923eda9b - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

    这是一个未删除的临时日志.请手动删除它.(1c773d57-4f35-40cf-ad62-bd757d5fcfae - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

  4. 构建自己的NSZombie

    当开启 xcode zombie 选项,发送消息到一个被  "释放了的对象"  时 ObjZomies *oz = [[ObjZomies alloc] init]; oz.nam ...

  5. Logstash——multiline 插件,匹配多行日志

    本文内容 测试数据 字段属性 按多行解析运行时日志 把多行日志解析到字段 参考资料 在处理日志时,除了访问日志外,还要处理运行时日志,该日志大都用程序写的,比如 log4j.运行时日志跟访问日志最大的 ...

  6. linux red hat 安装svn

    安装步骤如下: 1.yum install subversion   2.输入rpm -ql subversion查看安装位置,如下图:   我们知道svn在bin目录下生成了几个二进制文件. 输入 ...

  7. 【原创】从零开始学SpagoBI5.X源码汉化编译

    从零开始学SpagoBI5.X源码汉化编译 一.新建Tomact Server 服务器并配置测试1.文件-新建-其他-过滤server-服务类型选择Tomact V7.0 Server2.根据需要修改 ...

  8. java web项目启动时自动加载自定义properties文件

    首先创建一个类 public class ContextInitListener implements ServletContextListener 使得该类成为一个监听器.用于监听整个容器生命周期的 ...

  9. apache工作模式:prefork和worker

    apache作为现今web服务器用的最广泛也是最稳定的开源服务器软件,其工作模式有许多中,目前主要有两种模式:prefork模式和worker模式 一.两种模式 prefork模式: prefork是 ...

  10. SQL 存储过程入门(事务)(四)

    SQL 存储过程入门(事务)(四)   本篇我们来讲一下事务处理技术. 为什么要使用事务呢,事务有什么用呢,举个例子. 假设我们现在有个业务,当做成功某件事情的时候要向2张表中插入数据,A表,B表,我 ...