需要澄清 java 易失性关键字的行为

问题描述 投票:0回答:1

我一直在阅读有关“易失性”关键字的内容,因为我们的应用程序充满了这种类型的变量。这是很多年前完成的,现在回顾它我想确认一些观点。举个例子:

私有易失性int响应超时;

此变量负责存储我们的应用程序等待从后端服务器接收响应的最大等待时间。每次我们需要向后端发送请求时都会读取它,但几乎没有修改(可能每年一次)。

我们的应用程序是一个 API 网关,有数千个读取器线程,但只有一个写入器,偶尔会写入一些易失性变量。

据我了解:

  • 如果responseTimeout是易失性的,值为3000,并且线程B将其更改为5000,则在此写入之后,所有读取器线程将立即看到新值5000。
  • 如果responseTimeout不是易失性的,值为3000,并且线程B将其更改为5000,则在此写入之后,一些读取线程将立即看到新值5000,而其他一些线程仍会在短时间内看到旧值3000 (直到更改传播到所有 CPU 寄存器)。

如果这是正确的,那么对于我们来说,在写入之后,一些线程在短时间内仍然可以看到旧值是可以接受的。这就是为什么我们计划删除这个“易失性”关键字。

所以问题来了。不会发生的是,某些读取器线程将看到不同的值 3000 或 5000,因为它们正在尝试读取线程 B 尚未完全写入的内容。这是真的吗?

谢谢。

java multithreading volatile
1个回答
0
投票

我们无法给出可靠的先验预测,即线程需要多长时间才能看到更新的值(如果删除

volatile
)。事实上,给定的线程可能“永远不会”看到更新的值。实际上,这取决于许多因素,包括 JIT 编译器版本、硬件 ISA、可用内核的数量、系统负载的负载情况以及应用程序线程工作方式的各个方面。 你的问题的另一面是:你希望通过这样做获得什么?您的系统负载是否如此之高,以至于每个请求额外读取一次

volatile

的成本会很大?您是否

测量过
性能影响? 另外,考虑替代方案。例如,如果您每年只更改一次,难道您不能将设置保存在

final

变量中并在需要更改设置时

重新启动
您的应用程序吗?

© www.soinside.com 2019 - 2024. All rights reserved.