Java Parallel Stream 源码深入解析,java项目面试实操

本文详细解读了Java中的ForkJoinTask在处理Spliterator切分和递归过程中的作用,以及与Spring框架(如SpringBoot和SpringMVC)在微服务场景中的结合,特别是并行流的实现原理和Spring中的任务合并策略。
摘要由CSDN通过智能技术生成

else {

forkRight = true;

task = rightChild;

taskToFork = leftChild;//leftChild.fork()

}

// 递归

taskToFork.fork();

sizeEstimate = rs.estimateSize();

}

task.setLocalResult(task.doLeaf());

task.tryComplete();

}

复制代码

本质上理解,就是将一个Spliterator进行切分成两部分,然后两部分再进行切分,直到while()条件无法再满足,然后对该部分进行运算,将运算结果保存在节点的LocalResult字段上。这部分就是分支的切分阶段。

结果合并


测试代码:

long count = Stream.of(1, 2, 3, 4, 5).parallel().reduce((x, y) -> x + y + 10).get();

复制代码

AbstractPipeline.evaluate() 方法是并行流与串行流的分叉点:

final R evaluate(TerminalOp<E_OUT, R> terminalOp) {

assert getOutputShape() == terminalOp.inputShape();

if (linkedOrConsumed)

throw new IllegalStateException(MSG_STREAM_LINKED);

linkedOrConsumed = true;

return isParallel()

? terminalOp.evaluateParallel(this, sourceSpliterator(terminalOp.getOpFlags())) //并行流执行点
terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags()));

}

复制代码

ReduceOps.evaluateParallel() 方法是其实现之一

@Override

public <P_IN> R evaluateParallel(PipelineHelper helper,

Spliterator<P_IN> spliterator) {

return new ReduceTask<>(this, helper, spliterator).invoke().get();

}

复制代码

主要做了两件事:

  • 创建一个ReduceTask任务

  • 任务调用invoke()执行

创建的逻辑没有额外的操作,就是将三个参数赋值到实例变量中。

invoke()是ForkJoinTask的方法,方法这里主要关注invoke() 方法的逻辑:

/**

  • Commences performing this task, awaits its completion if

  • necessary, and returns its result, or throws an (unchecked)

  • {@code RuntimeException} or {@code Error} if the underlying

  • computation did so.

  • @return the computed result

*/

public final V invoke() {

int s;

//执行任务

if ((s = doInvoke() & DONE_MASK) != NORMAL)

reportException(s);

// 这里放回的是最终结果

return getRawResult();

}

复制代码

/**

  • Implementation for invoke, quietlyInvoke.

  • @return status upon completion

*/

private int doInvoke() {

int s; Thread t; ForkJoinWorkerThread wt;

return (s = doExec()) < 0 ? s :

((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?

(wt = (ForkJoinWorkerThread)t).pool.

awaitJoin(wt.workQueue, this, 0L) :

externalAwaitDone();

}

==> JDK代码为了性能,牺牲了可读性,这里整理下:

private int doInvoke() {

s = doExec();

if (s < 0) return s;

t = Thread.currentThread();

if (t instanceof ForkJoinWorkerThread) {

ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t.pool();

return wt.awaitJoin(wt.workQueue,this,0L);

}

return externalAwaitDone();

}

复制代码

/**

  • If the pending count is nonzero, decrements the count;

  • otherwise invokes {@link #onCompletion(CountedCompleter)}

  • and then similarly tries to complete this task’s completer,

  • if one exists, else marks this task as complete.

*/

public final void tryComplte() {

CountedCompleter<?> a = this, s = a;

for (int c;😉 {

if ((c = a.pending) == 0) {

a.onCompletion(s);

if ((a = (s = a).completer) == null) {

s.quietlyComplete();

return;

}

}

else if (U.compareAndSwapInt(a, PENDING, c, c - 1))

return;

}

}

复制代码

ReduceOps.onCompletion() 的重写方法中,如果是不是叶子节点,则合并两个子节点的结果:

@Override

public void onCompletion(CountedCompleter<?> caller) {

if (!isLeaf()) {

//如果不是叶子节点,将左右两个子节点的结果合并。

S leftResult = leftChild.getLocalResult();

leftResult.combine(rightChild.getLocalResult());

setLocalResult(leftResult);

}

// GC spliterator, left and right child

super.onCompletion(caller);

}

复制代码

关注里面3个方法:

  • isLeaf()

  • combine()

  • super.onCompletion()

isLeaf()判断是不是叶子节点,只有非叶子节点才有两个子节点,然后才能进行合并任务:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

Spring全套教学资料

Spring是Java程序员的《葵花宝典》,其中提供的各种大招,能简化我们的开发,大大提升开发效率!目前99%的公司使用了Spring,大家可以去各大招聘网站看一下,Spring算是必备技能,所以一定要掌握。

目录:

部分内容:

Spring源码

  • 第一部分 Spring 概述
  • 第二部分 核心思想
  • 第三部分 手写实现 IoC 和 AOP(自定义Spring框架)
  • 第四部分 Spring IOC 高级应用
    基础特性
    高级特性
  • 第五部分 Spring IOC源码深度剖析
    设计优雅
    设计模式
    注意:原则、方法和技巧
  • 第六部分 Spring AOP 应用
    声明事务控制
  • 第七部分 Spring AOP源码深度剖析
    必要的笔记、必要的图、通俗易懂的语言化解知识难点

脚手框架:SpringBoot技术

它的目标是简化Spring应用和服务的创建、开发与部署,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用的微服务功能,可以和spring cloud联合部署。

Spring Boot的核心思想是约定大于配置,应用只需要很少的配置即可,简化了应用开发模式。

  • SpringBoot入门
  • 配置文件
  • 日志
  • Web开发
  • Docker
  • SpringBoot与数据访问
  • 启动配置原理
  • 自定义starter

微服务架构:Spring Cloud Alibaba

同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

  • 微服务架构介绍
  • Spring Cloud Alibaba介绍
  • 微服务环境搭建
  • 服务治理
  • 服务容错
  • 服务网关
  • 链路追踪
  • ZipKin集成及数据持久化
  • 消息驱动
  • 短信服务
  • Nacos Confifig—服务配置
  • Seata—分布式事务
  • Dubbo—rpc通信

Spring MVC

目录:

部分内容:

ZipKin集成及数据持久化

  • 消息驱动
  • 短信服务
  • Nacos Confifig—服务配置
  • Seata—分布式事务
  • Dubbo—rpc通信

[外链图片转存中…(img-UxJChgMN-1711947118652)]

[外链图片转存中…(img-prqXsNkE-1711947118652)]

Spring MVC

目录:

[外链图片转存中…(img-hzfm1IxO-1711947118652)]

[外链图片转存中…(img-qpd3srJa-1711947118652)]

[外链图片转存中…(img-bRYNY4nF-1711947118653)]

部分内容:

[外链图片转存中…(img-oUjzICpG-1711947118653)]

[外链图片转存中…(img-TLzadiMz-1711947118653)]

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值