zoukankan      html  css  js  c++  java
  • parallel stream-不能随便使用

    前言

    java8除了新增stream,还提供了parallel stream-多线程版的stream,parallel stream的优势是:充分利用多线程,提高程序运行效率,但是正确的使用并不简单,盲目使用可能导致以下后果

    1. 效率不增反降
    2. 增加额外的复杂度,程序更易出错
    3. 运行结果不正确

    效率不增反降

    parallel stream是基于fork/join框架的,简单点说就是使用多线程来完成的,使用parallel stream时要考虑初始化fork/join框架的时间,如果要执行的任务很简单,那么初始化fork/join框架的时间会远多于执行任务所需时间,也就导致了效率的降低.
    根据附录doug Lee的说明,任务数量*执行方法的行数>=10000或者执行的是消耗大量时间操作(如io/数据库)才有必要使用

    增加额外的复杂度,程序更易出错

    在spring框架中,假设有一组主键id,使用这组id去数据库获取记录

    //DB.fetchRecord(long id)使用当前线程session连接数据库
    ids.parallelStream().map(DB::fetchRecord).collect(Collections.toList());
    

    这里使用parallel stream是正确的,但是运行会报错,类似于 can't obtain session from current thread.原因就是多线程运行,对应的线程没有绑定的session,要完成上面的功能需要提供一个特殊版本的DB方法

    //不从线程获取session,而是在方法内部开启新的session
    DB.fetchRecordWithoutSession(long id)
    

    运行结果不正确

    还是以上面的例子,session问题已经解决,如果获取到的记录需要和ids顺序相同,那么使用parallel获取到的结果就是不正确的,原因还是多线程
    如何正确使用:

    1. 确保要执行的任务对线程环境没有依赖
    2. 任务消耗时间长/数据量大到不用思考是否要用parallel
    3. 结果没有顺序要求
  • 相关阅读:
    使用eclipse从github导入maven项目
    J2SE 8的Lambda --- Comparator
    J2SE 8的Lambda --- functions
    J2SE 8的Lambda --- 语法
    J2SE 8的流库 --- 收集处理结果
    J2SE 8的流库 --- 转换流, 得到的还是流
    J2SE 8的流库 --- 基本类型流的使用
    J2SE 8的流库 --- 生成流
    Hadoop 3.0 安装
    程序员到底要不要读研,过来人给你几点建议!
  • 原文地址:https://www.cnblogs.com/xzy-/p/10915920.html
Copyright © 2011-2022 走看看