我惊了!CompletableFuture居然有性能问题! (中)

简介: 我惊了!CompletableFuture居然有性能问题! (中)

但是后面跟了一个“problem”,这个“problem”就是说如果我们把多处理器这个值缓存起来了,假设程序运行的过程中出现了从多处理器到单处理器的运行环境变化这个值就不准确了,虽然这是一个不太可能的变化。但是即使这个“problem”真的发生了也没有关系,它只是会导致一个小小的性能损失。

所以就出现了前面大家看到的这样的代码,这就是 “we can cache this value in a field”:

image.png

而体现到具体的代码变更是这样的:

http://cr.openjdk.java.net/~shade/8227018/webrev.01/src/share/classes/java/util/concurrent/CompletableFuture.java.udiff.html


image.png

所以,当你去看这部分源码的时候,你会看到 SPINS 字段上其实还有很长一段话,是这样的:

image.png

给大家翻译一下:

1.在 waitingGet 方法中,进行阻塞操作前,进行旋转。

2.没有必要在单处理器上进行旋转。

3.调用 Runtime.availableProcessors 方法的成本是很高的,所以在此缓存该值。但是这个值是首次初始化时可用的 CPU 的数量。如果某系统在启动时只有一个 CPU 可以用,那么 SPINS 的值会被初始化为 0,即使后面再使更多的 CPU 在线,也不会发生变化。

当你有了前面的 BUG 的描述中的铺垫之后,你就明白了为什么这里写上了这么一大段话。

有的同学就真的去翻代码,也许你看到的是这样的:

image.png

什么情况?根本就看不到 SPINS 相关的代码啊,这不是欺骗老实人吗?

image.png

你别慌啊,猴急猴急的,我这不是还没说完嘛?

我们再把目光放到图片中的这句话上:

image.png

只需要在 JDK 8 中进行这个修复即可,因为 JDK 9 和更高版本的代码都不是这样的写的了。

比如在 JDK 9 中,直接拿掉了整个 SPINS 的逻辑,不要这个短暂的自旋等待了:

http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/f3af17da360b


image.png


虽然,拿掉了这个短暂的自旋等待,但是其实也算是学习了一个骚操作。

问:怎么在不引入时间的前提下,做出一个自旋等待的效果?

答案就是被拿掉的这段代码。

但是有一说一,我第一次看到这个代码的时候我就觉得别扭。这一个短短的自旋能延长多少时间呢?

加入这个自旋,是为了稍晚一点执行后续逻辑中的 park 代码,这个稍重一点的操作。但是我觉得这个 “brief spin-wait” 的收益其实是微乎其微的。

所以我也理解为什么后续直接把这一整坨代码拿掉了。而拿掉这一坨代码的时候,其实作者并没有意识到这里有 BUG。

而这里提到的作者,其实就是 Doug Lea 老爷子。

我为什么这样说呢?

依据就在这个 BUG 链接里面提到的编号为 8227018 的 BUG 中,它们其实描述的是同一个事情:

image.png

image.png


Holmes 在这里面提到了 “cache this value in a field” 的解决方案,并得到了 Doug 的同意。

Doug 说: JDK 9 已经不用 spin 了。

所以,我个人理解是 Doug 在不知道这个地方有 BUG 的情况下,拿掉了 SPIN 的逻辑。至于是出于什么考虑,我猜测是收益确实不大,且代码具有一定的迷惑性。还不如拿掉之后,理解起来直观一点。

Doug Lea 大家都耳熟能详, David Holmes 是谁呢?


image.png


《Java 并发编程实战》的作者之一,端茶就完事了。


image.png


而你要是对我以前的文章印象足够深刻,那么你会发现早在《Doug Lea在J.U.C包里面写的BUG又被网友发现了。》这篇文章里面,他就已经出现过了:

image.png

老朋友又出现了,建议铁汁们把梦幻联动打在公屏上。

目录
相关文章
|
18天前
|
监控 Java API
Spring WebFlux 响应式编程技术详解与实践指南
本文档全面介绍 Spring WebFlux 响应式编程框架的核心概念、架构设计和实际应用。作为 Spring 5 引入的革命性特性,WebFlux 提供了完全的响应式、非阻塞的 Web 开发栈,能够显著提升系统的并发处理能力和资源利用率。本文将深入探讨 Reactor 编程模型、响应式流规范、WebFlux 核心组件以及在实际项目中的最佳实践,帮助开发者构建高性能的响应式应用系统。
175 0
|
5月前
|
Arthas 运维 监控
Arthas monitor(方法执行监控)
Arthas monitor(方法执行监控)
406 0
|
关系型数据库 MySQL 调度
DataX教程(05)- DataX Web项目实践
DataX教程(05)- DataX Web项目实践
2437 0
|
Java Maven 开发者
@EnableFeignClients:简化微服务间调用的艺术
@EnableFeignClients:简化微服务间调用的艺术
1731 2
|
应用服务中间件 nginx
Nginx 出现403 Forbidden 的几种解决方案【已解决】
Nginx 出现403 Forbidden 的几种解决方案【已解决】
10366 3
|
网络协议 Java
【Java】已解决java.net.UnknownHostException异常
【Java】已解决java.net.UnknownHostException异常
3232 0
|
Arthas 人工智能 监控
JVM工作原理与实战(三十五):性能调优
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了性能调优、性能调优案例等内容。
440 1
|
Java
Java接口中可以定义哪些方法?
【4月更文挑战第13天】
839 0
Java接口中可以定义哪些方法?
|
11月前
|
Java Spring
【亲测有效完结bug】org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exce
【亲测有效完结bug】org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exce
1438 0
|
安全 Java 数据安全/隐私保护
Spring Boot中的数据加密与解密
Spring Boot中的数据加密与解密