千家信息网

java8有哪些新功能

发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,这篇文章主要讲解了"java8有哪些新功能",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"java8有哪些新功能"吧!并行流认识开启并行流并行流是什么?
千家信息网最后更新 2024年11月28日java8有哪些新功能

这篇文章主要讲解了"java8有哪些新功能",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"java8有哪些新功能"吧!

并行流

认识开启并行流

并行流是什么?是把一个流内容分成多个数据块,并用不同线程分别处理每个不同数据块的流。例如,有下面一个例子,在List中,需要对List数据进行分别计算,其代码如下所示:

List appleList = new ArrayList<>(); // 假装数据是从库里查出来的  for (Apple apple : appleList) {     apple.setPrice(5.0 * apple.getWeight() / 1000); }

在这里,时间复杂度为O(list.size),随着list的增加,耗时也在增加。并行流可以解决这个问题,代码如下所示:

appleList.parallelStream().forEach(apple -> apple.setPrice(5.0 * apple.getWeight() / 1000));

这里通过调parallelStream()说明当前流为并行流,然后进行并行执行。并行流内部使用了默认的ForkJoinPool线程池,默认线程数为处理器的核心数。

测试并行流

普通代码如下所示:

public static void main(String[] args) throws InterruptedException {     List appleList = initAppleList();      Date begin = new Date();     for (Apple apple : appleList) {         apple.setPrice(5.0 * apple.getWeight() / 1000);         Thread.sleep(1000);     }     Date end = new Date();     log.info("苹果数量:{}个, 耗时:{}s", appleList.size(), (end.getTime() - begin.getTime()) /1000); }

输出的内容为耗时4s。

并行代码如下所示:

List appleList = initAppleList();  Date begin = new Date(); appleList.parallelStream().forEach(apple ->                                    {                                        apple.setPrice(5.0 * apple.getWeight() / 1000);                                        try {                                            Thread.sleep(1000);                                        } catch (InterruptedException e) {                                            e.printStackTrace();                                        }                                    }                                   ); Date end = new Date(); log.info("苹果数量:{}个, 耗时:{}s", appleList.size(), (end.getTime() - begin.getTime()) /1000);

输出结果为耗时1s。可以看到耗时大大提升了3s。

并行流拆分会影响流的速度

对于并行流来说需要注意以下几点:

对于 iterate 方法来处理的前 n 个数字来说,不管并行与否,它总是慢于循环的,

而对于 LongStream.rangeClosed() 方法来说,就不存在 iterate 的第两个痛点了。它生成的是基本类型的值,不用拆装箱操作,另外它可以直接将要生成的数字 1 - n 拆分成 1 - n/4, 1n/4 - 2n/4, ... 3n/4 - n 这样四部分。因此并行状态下的 rangeClosed() 是快于 for 循环外部迭代的

代码如下所示:

package lambdasinaction.chap7;  import java.util.stream.*;  public class ParallelStreams {      public static long iterativeSum(long n) {         long result = 0;         for (long i = 0; i <= n; i++) {             result += i;         }         return result;     }      public static long sequentialSum(long n) {         return Stream.iterate(1L, i -> i + 1).limit(n).reduce(Long::sum).get();     }      public static long parallelSum(long n) {         return Stream.iterate(1L, i -> i + 1).limit(n).parallel().reduce(Long::sum).get();     }      public static long rangedSum(long n) {         return LongStream.rangeClosed(1, n).reduce(Long::sum).getAsLong();     }      public static long parallelRangedSum(long n) {         return LongStream.rangeClosed(1, n).parallel().reduce(Long::sum).getAsLong();     }  } package lambdasinaction.chap7;  import java.util.concurrent.*; import java.util.function.*;  public class ParallelStreamsHarness {      public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool();      public static void main(String[] args) {         System.out.println("Iterative Sum done in: " + measurePerf(ParallelStreams::iterativeSum, 10_000_000L) + " msecs");         System.out.println("Sequential Sum done in: " + measurePerf(ParallelStreams::sequentialSum, 10_000_000L) + " msecs");         System.out.println("Parallel forkJoinSum done in: " + measurePerf(ParallelStreams::parallelSum, 10_000_000L) + " msecs" );         System.out.println("Range forkJoinSum done in: " + measurePerf(ParallelStreams::rangedSum, 10_000_000L) + " msecs");         System.out.println("Parallel range forkJoinSum done in: " + measurePerf(ParallelStreams::parallelRangedSum, 10_000_000L) + " msecs" );     }      public static  long measurePerf(Function f, T input) {         long fastest = Long.MAX_VALUE;         for (int i = 0; i < 10; i++) {             long start = System.nanoTime();             R result = f.apply(input);             long duration = (System.nanoTime() - start) / 1_000_000;             System.out.println("Result: " + result);             if (duration < fastest) fastest = duration;         }         return fastest;     } }

共享变量会造成数据出现问题

public static long sideEffectSum(long n) {     Accumulator accumulator = new Accumulator();     LongStream.rangeClosed(1, n).forEach(accumulator::add);     return accumulator.total; }  public static long sideEffectParallelSum(long n) {     Accumulator accumulator = new Accumulator();     LongStream.rangeClosed(1, n).parallel().forEach(accumulator::add);     return accumulator.total; }  public static class Accumulator {     private long total = 0;      public void add(long value) {         total += value;     } }

并行流的注意

  1. 尽量使用 LongStream / IntStream / DoubleStream 等原始数据流代替 Stream 来处理数字,以避免频繁拆装箱带来的额外开销

  2. 要考虑流的操作流水线的总计算成本,假设 N 是要操作的任务总数,Q 是每次操作的时间。N * Q 就是操作的总时间,Q 值越大就意味着使用并行流带来收益的可能性越大

  3. 对于较少的数据量,不建议使用并行流

  4. 容易拆分成块的流数据,建议使用并行流

感谢各位的阅读,以上就是"java8有哪些新功能"的内容了,经过本文的学习后,相信大家对java8有哪些新功能这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

数据 代码 新功能 内容 数字 时间 线程 问题 处理 学习 不同 就是 建议 拆装 数量 方法 苹果 循环 生成 输出 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 微信不能连接服务器是什么意思 手机软件开发人员兼职 网络安全进校国手抄报 论坛服务器和数据库 盐城服务器托管 延安软件开发联系方式 OUTLAST下载软件开发 用数据库如何销售管理 大学有开展网络安全专业吗 网络安全 文明上网演讲稿 标题读取数据库更新 信息处理与网络安全心得体会 日常工作巡查中发现网络安全隐患 大话2虎啸神州服务器 求生之路rpg服务器怎么做 基于大数据的网络安全研究 现代网络技术pdf下载 网络安全最新科研 租个云数据库多少钱 四川省美食互联网科技公司 松江区品牌软件开发值得推荐 2021网络技术职高高考试题 分布式数据库在当下发展的优势 我的世界1.16.5怎么开服务器 装修工程项目管理软件开发价格 小单位可以用nas做服务器吗 中国海洋大学考研网络安全 网站服务器管理软件有哪些 网络安全 问卷 青浦区共享陪护床软件开发
0