• java8新特性——并行流与顺序流


      在我们开发过程中,我们都知道想要提高程序效率,我们可以启用多线程去并行处理,而java8中对数据处理也提供了它得并行方法,今天就来简单学习一下java8中得并行流与顺序流。

      并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。

      Java8中将并行流进行了优化,我们可以很容易的对数据进行并行操作。Stream API可以声明性地通过parallel()与scqucntial()在并行流与顺序流之间进行切换。

    一、Fork—Join框架

      Fork—Join框架:是java7提供得一个用于执行任务得框架,就是在必要得情况下,将一个大任务,进行拆分(Fork)成若干个小任务(拆分到不能再拆分),再将一个个的小任务运算得结果进行join汇总。

      Fork—Join框架时ExecutorService接口得一种具体实现,目的是为了帮助更好地利用多处理器带来得好处。它是为那些能够被递归地拆分成子任务的工作类型量身设计的。起目的在于能够使用所有有可用的运算能力来提升你的应用的性能。

      Fork—Join框架会将任务分发给线程池中的工作线程。Fork—Join框架的独特之处在与它使用工作窃取(work-stealing)算法。完成自己的工作而处于空闲的工作线程能够从其他仍处于忙碌(busy)状态的工作线程中窃取等待任务执行,每个工作线程都有自己的工作队列,这是使用双端队列(deque)来实现的。当一个任务划分一个新线程时,它将自己推到deque的头部。当线程的任务队列为空,它将尝试从另一个线程的deque的尾部窃取另一个任务。

      下面,我们来写一个简单的实例来演示一下:

     1 /**
     2  * 要想使用Fark—Join,类必须继承RecursiveAction(无返回值) 或者
     3  * RecursiveTask(有返回值)
     4  * @author Wuyouxin
     5  *
     6  */
     7 public class ForkJoin extends RecursiveTask<Long>{
     8     
     9     /**
    10      * 序列化
    11      */
    12     private static final long serialVersionUID = -645248615909548422L;
    13 
    14     private long start;
    15     private long end;
    16     
    17     public ForkJoin(long start, long end) {
    18         this.start = start;
    19         this.end = end;
    20     }
    21 
    22     private static final long THRESHOLD = 10000L;
    23     /**
    24      * 重写方法
    25      */
    26     @Override
    27     protected Long compute() {
    28         if (end - start <= THRESHOLD) {
    29             long sum = 0;
    30             for (long i = start; i < end; i++) {
    31                 sum += i;
    32             }
    33             return sum;
    34         } else {
    35             long middle = (end -start)/2;
    36             ForkJoin left = new ForkJoin(start, middle);
    37             //拆分子任务,压入线程队列
    38             left.fork();
    39             ForkJoin right = new ForkJoin(middle, end);
    40             right.fork();
    41             
    42             //合并并返回
    43             return left.join() + right.join();
    44         }
    45     }
    46     
    47 }
     1     /**
     2      * 实现数的累加
     3      */
     4     @Test
     5     public void test1() {
     6         //开始时间
     7         Instant start = Instant.now();
     8         
     9         //这里需要一个线程池的支持
    10         ForkJoinPool pool = new ForkJoinPool();
    11         
    12         ForkJoinTask<Long> task = new ForkJoin(0, 10000000000L);
    13         
    14         long sum = pool.invoke(task);
    15         
    16         //结束时间
    17         Instant end = Instant.now();
    18         System.out.println(Duration.between(start, end).getSeconds());
    19     }

    二、java8 并行流

      java8 中 对并行流做了优化,简化了许多,我们继续以累加来写个例子。

     1     /**
     2      * java8 并行流 parallel()
     3      */
     4     @Test
     5     public void test2() {
     6         //开始时间
     7         Instant start = Instant.now();
     8         
     9         LongStream.rangeClosed(0, 10000000000L).parallel()
    10         .reduce(0, Long :: sum);
    11         
    12         //结束时间
    13         Instant end = Instant.now();
    14         System.out.println(Duration.between(start, end).getSeconds());
    15     }

      java8 中不仅仅对代码进行了优化,而且效率也大大提升。

  • 相关阅读:
    谈谈对MapTask任务分配和Shuffle的理解
    Yarn的资源调优
    @section Scripts{}的使用
    数据提高查询速度的方法(摘抄)
    customErrors 元素(ASP.NET 设置架构)
    成员资格、授权和安全性(一)
    MVC5发展历程,从MVC2谈起
    轻量级记事本工具:CintaNotes
    CF459E Pashmak and Graph [dp]
    【模板】拉格朗日插值
  • 原文地址:https://www.cnblogs.com/wuyx/p/9098128.html
Copyright © 2020-2023  润新知