gpt4 book ai didi

java - 下面的 JAVA 代码遇到了什么同步问题?

转载 作者:行者123 更新时间:2023-11-30 09:26:51 25 4
gpt4 key购买 nike

作者 this page提到下面的第二个代码示例存在同步问题,但代码将在 100 次中运行大约 99 次。我无法在该页面中看到两个程序的操作差异。


结合前两者的更通用的解决方案是将字段的值复制到局部变量中,然后仅更改局部变量。该字段在方法内保持不变。例如,

public class Counter {

int count = 0;

public void count() {
int count = this.count;
int limit = count + 100;
while (count++ != limit) System.out.println(count);
}

}

注意局部变量 count 如何隐藏字段计数,以及如何使用 this 关键字来引用阴影之外的字段计数。

当您不需要在方法完成后将更改的变量保存回字段时,此技巧主要有用。以下保存了状态,但仍然存在不太明显的同步问题。

public class Counter {

private int count = 0;

public void count() {
int count = this.count;
int limit = count + 100;
while (count++ != limit) System.out.println(count);
this.count = count;
}

}

事实上,这可能比原始示例更糟糕,因为在 100 次中它会工作 99 次。如果您不在源代码中发现这里的错误,则很难确定它。

最佳答案

问题在于对 this.count 的修改不是原子的。

假设有两个线程正在调用此函数,并且 this.count 当前设置为 0

线程 1 将 0 加载到其本地 count 中,然后开始将其递增到 101(不是 100,因为以前认为是因为它在达到限制后将 count 增加一次,count++ != limit)。

与此同时,线程 2 进入并且 this.count 仍然设置为 0 所以它捕获它并开始递增到 101

在某个时候,它们都到达 this.count = count 行(顺序无关紧要)并且它们设置了 this。数到101。

最后应该设置的是 202(我认为 - 当然应该在 200 标记附近) .

第一段代码之所以有效,是因为它实际上并没有尝试更改 this.count 值,因此不可能出现竞争条件。

关于java - 下面的 JAVA 代码遇到了什么同步问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14823494/

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