java8中forkjoin和optional框架使用

并行流与串行流

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

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

了解 Fork/Join 框架

Fork/Join 框架:就是在必要的情况下,将一个大任务,进形拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运行的结果进行join汇总。

Fork/Join 框架与传统线程池的区别:

采用“工作窃取”模式(work-stealing):

当执行新的任务时,它可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。

相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的处理方式上.在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态.而在fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而无法继续运行.那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行.这种方式减少了线程的等待时间,提高了性能。

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;
public class TestForkJoin {
  public static void main(String[] xx){

  }
  private static void test1(){
  	Instant start=Instant.now();
    ForkJoinPool pool=new ForkJoinPool();
    ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L);
    long sum = pool.invoke(task);
    System.out.println(sum);

    Instant end=Instant.now();
    System.out.println("消耗时间"+Duration.between(start, end).toMillis()+"ms");//消耗时间3409ms
  }
  private static void test2(){
    Instant start=Instant.now();

    Long sum = LongStream.rangeClosed(0L, 10000L)
               .parallel()
               .reduce(0,Long::sum);
    System.out.println(sum);

    Instant end=Instant.now();
    System.out.println("消耗时间" + Duration.between(start, end).toMillis()+"ms");//消耗时间2418ms
  }
}
class ForkJoinCalculate extends RecursiveTask<Long>{

  private static final long serialVersionUID = 1234567890L;//序列号

  private long start;
  private long end;
  private static final long THRESHOLD=2500000000L;//临界值

  public ForkJoinCalculate(long start,long end) {
    this.start=start;
    this.end=end;
  }
  @Override
  protected Long compute() {
    long length = end - start;
    if(length <= THRESHOLD){
      long sum=0;
      for(long i = start; i <= end; i++){
        sum += i;
      }
      return sum;
    }else{
      long middle = (start+end)/2;
      ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
      left.fork();

      ForkJoinCalculate right=new ForkJoinCalculate(middle+1, end);
      right.fork();

      return left.join() + right.join();
    }
  }

}

Optional类

Optional< T>类(java.util.Optional) 是一个容器类,代表一个值存在或不存在。

原来用null表示一个值不存在,现在 Optional可以更好的表达这个概念。并且可以避免空指针异常。

常用方法:

Optional.of(T t) : 创建一个 Optional 实例

Optional.empty() : 创建一个空的 Optional 实例

Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例

isPresent() : 判断是否包含值

orElse(T t) : 如果调用对象包含值,返回该值,否则返回t

orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值

map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()

flatMap(Function mapper):与 map 类似,要求返回值必须是Optional

public class OptionalTest1 {
  public static void main(String[] args){

  	String s = new String("Ha");
//  	Optional<String> op = Optional.of(null);
//
//  	String s1 = op.get();
//  	System.out.println(s1);

//  	Optional<String> op1 = Optional.empty();
//  	String s1 = op1.get();
//  	System.out.println(s1);  

  	Optional<String> op1 = Optional.ofNullable(null);
//  	System.out.println(op1.isPresent());
//  	System.out.println(op1.orElse(new String("Google")));
  	//System.out.println(op1.orElseGet(() -> new String("Ali")));

  	Optional<String> op2 = op1.map((x) -> x.toLowerCase());
  	String s2 = op2.get();
  	System.out.println(s2);
  }
}
@Test
  public void test5(){
    Man man=new Man();
    String name=getGodnessName(man);
    System.out.println(name);
  }
  //需求:获取一个男人心中女神的名字
  public String getGodnessName(Man man){
    if(man!=null){
      Godness g=man.getGod();
      if(g!=null){
        return g.getName();
      }
    }
    return "苍老师";
  }
  //运用Optional的实体类
  @Test
  public void test6(){
    Optional<Godness> godness=Optional.ofNullable(new Godness("林志玲"));
    Optional<NewMan> op=Optional.ofNullable(new NewMan(godness));
    String name=getGodnessName2(op);
    System.out.println(name);
  }
  public String getGodnessName2(Optional<NewMan> man){
    return man.orElse(new NewMan())
         .getGodness()
         .orElse(new Godness("苍老师"))
         .getName();
  }
//注意:Optional 不能被序列化
public class NewMan {
  private Optional<Godness> godness = Optional.empty();
  private Godness god;
  public Optional<Godness> getGod(){
    return Optional.of(god);
  }
  public NewMan() {
  }
  public NewMan(Optional<Godness> godness) {
    this.godness = godness;
  }
  public Optional<Godness> getGodness() {
    return godness;
  }
  public void setGodness(Optional<Godness> godness) {
    this.godness = godness;
  }
  @Override
  public String toString() {
    return "NewMan [godness=" + godness + "]";
  }
}

以上就是我们给大家整理的java8中forkjoin和optional框架使用心得的全部内容,大家在学习的时候如果还有任何不明白的地方可以在下方的留言区讨论。

(0)

相关推荐

  • java IO流将一个文件拆分为多个子文件代码示例

    文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并.很多高大上的分布式文件系统(比如:google的GFS.taobao的TFS)里,也是按block为单位,对文件进行分割或合并. 看下基本思路: 如果有一个大文件,指定分割大小后(比如:按1M切割) step 1: 先根据原始文件大小.分割大小,算出最终分割的小文件数N step 2: 在磁盘上创建这N个小文件 step 3: 开多个线程(线程数=分割文件数),每个线程里,利用RandomAccessF

  • Java中io流解析及代码实例

    IO流 Java中IO流分为两种,字节流和字符流,顾名思义字节流就是按照字节来读取和写入的,字符刘是按照字符来存取的:常用的文件读取用的就是字符流,在网络通信里面用的就是字节流 下面这张图是Java中IO流的总体框架: 字节流 Java中字节流一般都是以stream结尾的,输入的字节流叫InputStream,输出字节流叫OutputStream;InputStream和OutputStream是表示自己输入/输出的所有类的超类,是抽象类(abstract) 常用的字节流有: 1.FileInp

  • java IO流读取图片供前台显示代码分享

    最近项目中需要用到IO流来读取图片以提供前台页面展示,由于以前一直是用url路径的方式进行图片展示,一听说要项目要用IO流读取图片感觉好复杂一样,但任务下达下来了,做为程序员只有选择去执行喽,于是找了点资料看了会api, 嘿感觉挺简单的,由于是第一次采用IO流的方式进行读取图片供页面显示,所以把以下代码记录一下 后台代码: /** * IO流读取图片 by:long * @return */ @RequestMapping(value = "/IoReadImage/{imgName}"

  • Java文件读写IO/NIO及性能比较详细代码及总结

    干Java这么久,一直在做WEB相关的项目,一些基础类差不多都已经忘记.经常想得捡起,但总是因为一些原因,不能如愿. 其实不是没有时间,只是有些时候疲于总结,今得空,下定决心将丢掉的都给捡起来. 文件读写是一个在项目中经常遇到的工作,有些时候是因为维护,有些时候是新功能开发.我们的任务总是很重,工作节奏很快,快到我们不能停下脚步去总结. 文件读写有以下几种常用的方法 1.字节读写(InputStream/OutputStream) 2.字符读取(FileReader/FileWriter) 3.

  • java的IO流详细解读

    流,就是一系列的数据. 当不同介质之间有数据交互的时候,JAVA就使用流来实现.数据源可以是文件,还可以是数据库.网络甚至其他的程序. 比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流. 字节流(以字节的形式读取和写入数据) InputStream字节输入流同时也是抽象类,只提供方法声明,不提供方法的具体实现. FileInputStream是InputStream的子类,下面以FileInputStream为例进行文件读取 package testIO; import java.i

  • java IO数据操作流、对象序列化、压缩流代码解析

    数据操作流 在io包中,提供了两个与平台无关的数据操作流: 数据输入流(DataInputStream) 数据输出流(DataOutputStream) 通常数据输出流会按一定格式将数据输出,再通过数据输入流按照一定格式将数据读入 DataOutputStream接口定义了一系列的writeXxx()的操作,可以写入各种数据类型的数据. 范例:使用数据操作流写入与读出数据 import java.io.DataOutputStream ; import java.io.File ; import

  • Java NIO框架Netty简单使用的示例

    之前写了一篇文章:Java 网络IO编程总结(BIO.NIO.AIO均含完整实例代码),介绍了如何使用Java原生IO支持进行网络编程,本文介绍一种更为简单的方式,即Java NIO框架. Netty是业界最流行的NIO框架之一,具有良好的健壮性.功能.性能.可定制性和可扩展性.同时,它提供的十分简单的API,大大简化了我们的网络编程. 同Java IO介绍的文章一样,本文所展示的例子,实现了一个相同的功能. 1.服务端 Server: package com.anxpp.io.calculat

  • IO中flush()函数的使用代码示例

    The java.io.Writer.flush() method flushes the stream. If the stream has saved any characters from the various write() methods in a buffer, write them immediately to their intended destination. Then, if that destination is another character or byte st

  • java8中forkjoin和optional框架使用

    并行流与串行流 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作.Stream API 可以声明性地通过 parallel()与 sequential()在并行流与顺序流之间进行切换. 了解 Fork/Join 框架 Fork/Join 框架:就是在必要的情况下,将一个大任务,进形拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运行的结果进行join汇总. Fork/Join 框架

  • Java8中新特性Optional、接口中默认方法和静态方法详解

    前言 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性. Java 8是Java的一个重大版本,有人认为,虽然这些新特性领Java开发人员十分期待,但同时也需要花不少精力去学习.下面本文就给大家详细介绍了Java8中新特性Optional.接口中默认方法和静态方法的相关内容,话不多说了,来一起看看详细的介绍吧. Optional Optional 类(java.util.Optional) 是一个

  • Java8中Optional类型和Kotlin中可空类型的使用对比

    本文主要给大家介绍了关于Java8中Optional类型和Kotlin中可空类型使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 在 Java 8中,我们可以使用 Optional 类型来表达可空的类型. package com.easy.kotlin; import java.util.Optional; import static java.lang.System.out; /** * Optional.ofNullable - 允许传递为 null 参数 *

  • 详解Java8中的lambda表达式、::符号和Optional类

    Java8中的lambda表达式.::符号和Optional类 0. 函数式编程 函数式编程(Functional Programming)属于编程范式(Programming Paradigm)中的用语,此外还有命令式编程(Imperative Programing)等,有兴趣的同学可以自行了解,我们这里大概解释一下函数式编程,在函数式编程中,输入一旦确定了,输出都确定了,函数调用的结果只依赖于传入的输入变量和内部逻辑,不依赖于外部,这样的写出的函数没有副作用.举个例子: public cla

  • Java8中Optional类的使用说明

    目录 简介 历史 null带来的种种问题 方案 场景引入 方法说明 构造函数 创建Optional对象 使用map从Optional对象中提取和转换值 使用flatMap链接Optional对象 默认行为及解引用Optional对象1 默认行为及解引用Optional对象2 使用filter剔除特定的值 实战 总结 简介 optional类是java8中引入的针对NPE问题的一种优美处理方式,源码作者也希望以此替代null. 历史 1965年,英国一位名为Tony Hoare的计算机科学家在设计

  • Java8中Optional操作的实际应用

    目录 简介 正文 1. Optional是什么 2. 没它 VS 有它 3. 核心操作 4. 应用 总结 总结 简介 目的:Optional的出现主要是为了解决null指针问题,也叫NPE(NullPointerException) 外形:Optional外形酷似容器(其实它就是一个容器),只是这个容器比较特殊,因为它只能存放一个对象,运气不好的话这个对象还是个null 操作:Optional从操作上来看,又跟前面的Stream流式操作很像,比如过滤filter - 提取map等 下面我们用比较

  • 详解Java8中Optional的常见用法

    目录 一. 简介 二.Java8 之前,空指针异常判断 三.Optional的使用 1.创建Optional实例 2.访问 Optional 对象的值 3.返回默认值 4.返回异常 (常用) 5.转换值 6.过滤值 一. 简介 Opitonal是java8引入的一个新类,目的是为了解决空指针异常问题.本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空. Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范式中实现.但是 Optional

  • 通过实例解析java8中的parallelStream

    这篇文章主要介绍了通过实例解析java8中的parallelStream,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 about Stream 什么是流? Stream是java8中新增加的一个特性,被java猿统称为流. Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator.原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作:高级版本的 Stream

  • 深入浅出Java8中parallelStream的使用

    about Stream 什么是流? Stream是java8中新增加的一个特性,被java猿统称为流. Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator.原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作:高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 "过滤掉长度大于 10 的字符串"."获取每个字符串的首字母"等,Stream 会隐式地在

  • 初识Java8中的Stream

    lambda表达式是stream的基础,初学者建议先学习lambda表达式,http://www.jb51.net/article/121129.htm 1.初识stream 先来一个总纲: 东西就是这么多啦,stream是java8中加入的一个非常实用的功能,最初看时以为是io中的流(其实一点关系都没有),让我们先来看一个小例子感受一下: @Before public void init() { random = new Random(); stuList = new ArrayList<St

随机推荐