gpt4 book ai didi

java - 基本的 Java 线程问题

转载 作者:搜寻专家 更新时间:2023-11-01 03:14:44 24 4
gpt4 key购买 nike

假设我正在与一个系统进行交互,该系统具有两个相互依赖的递增计数器(这些计数器永远不会递减):int totalFoos;//barredFoos 加上 nonBarredFoosint barredFoos;

我也有两种方法:int getTotalFoos();//基本上是对本地主机的网络调用int getBarredFoos();//基本上是对本地主机的网络调用

这两个计数器由我无权访问的代码保存和递增。假设它在备用线程上递增两个计数器,但以线程安全的方式递增(即在任何给定时间点,两个计数器将同步)。

在单个时间点准确计算 barredFoos 和 nonBarredFoos 的最佳方法是什么?

完全天真的实现:

int totalFoos = getTotalFoos();
int barredFoos = getBarredFoos();
int nonBarredFoos = totalFoos - barredFoos;

这有一个问题,即系统可以在两个方法调用之间递增两个计数器,然后我的两个副本将不同步,并且 barredFoos 的值将大于 totalFoos 被提取。

基本的双重检查实现:

while (true) {
int totalFoos = getTotalFoos();
int barredFoos = getBarredFoos();

if (totalFoos == getTotalFoos()) {
// totalFoos did not change during fetch of barredFoos, so barredFoos should be accurate.
int nonBarredFoos = totalFoos - barredFoos;
break;
}

// totalFoos changed during fetch of barredFoos, try again
}

这在理论上应该可行,但我不确定 JVM 是否保证这就是在考虑优化等因素后实际发生的情况。有关这些问题的示例,请参阅 http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html (链接来自 Romain Muller)。

考虑到我拥有的方法和上面关于计数器实际上一起更新的假设,有没有一种方法可以保证我的两个计数的副本是同步的?

最佳答案

是的,我相信你的实现就足够了;真正的工作是确保 getTotalFoosgetBarredFoos 返回的值确实同步并始终返回最新值。但是,正如您所说,情况已经如此。

当然,您可能会遇到此代码的一件事是无限循环;你会想要确保在这么短的时间内改变两个值将是一种非常特殊的情况,即使那样我认为建立安全性(即最大迭代次数)以避免得到绝对是明智的陷入无限循环。如果这些计数器的值在您无权访问的代码中,您不希望完全依赖这样一个事实,即在另一端永远不会出错。

关于java - 基本的 Java 线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1842009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com