Java 为什么Volatile不';当一个字段的值取决于它以前的值时,它不起作用
我偶然发现了这句话,我想不出理由 当字段的值取决于其属性时,Volatile不起作用 先前值 任何带有示例的解释都是非常值得赞赏的。“不起作用”是一个非常模糊的说法,但我怀疑问题的关键是,如果您有两个线程各自使用此代码执行一个循环:Java 为什么Volatile不';当一个字段的值取决于它以前的值时,它不起作用,java,volatile,Java,Volatile,我偶然发现了这句话,我想不出理由 当字段的值取决于其属性时,Volatile不起作用 先前值 任何带有示例的解释都是非常值得赞赏的。“不起作用”是一个非常模糊的说法,但我怀疑问题的关键是,如果您有两个线程各自使用此代码执行一个循环: field = field + 1 。。。那么,即使是不稳定的,每次迭代都是有效的: 阅读 使用我们读取的值执行计算 写 如果一个线程执行读取,然后另一个线程执行写入,那么当第一个线程执行写入时,它实际上将忽略第二个线程的写入 回到我们的例子,如果你有两个线程,每
field = field + 1
。。。那么,即使是不稳定的,每次迭代都是有效的:
field=field+1
,那么field
的值的总增加量可能不会达到两百万。“不起作用”是一个相当模糊的说法,但我怀疑问题的关键在于,如果有两个线程分别使用以下代码执行循环:
field = field + 1
。。。那么,即使是不稳定的,每次迭代都是有效的:
field=field+1
的一百万次迭代,那么field
值的总增加量可能不会达到两百万次。以下是一个示例:
volatile int i:
public void m() {
if (i == 0) i = 1;
else i = 2;
}
您可以让两个线程检查该条件,查看i是否为0并将其设置为1,尽管您可能希望两次运行该方法会将i设置为2。这是一个经典的“先检查后行动”场景
问题在于,波动性为您提供了可见性保证,但没有原子性保证。以下是一个示例:
volatile int i:
public void m() {
if (i == 0) i = 1;
else i = 2;
}
您可以让两个线程检查该条件,查看i是否为0并将其设置为1,尽管您可能希望两次运行该方法会将i设置为2。这是一个经典的“先检查后行动”场景
问题是,波动性为您提供了可见性保证,但没有原子性保证。FYI…我在Bruce EckelFYI的《Java思考》一书中找到了这条语句…我在Bruce EckelFYI的《Java思考》一书中找到了这条语句感谢您通过检查然后行动场景解释这一点。我对波动性为何/如何依赖于变量的先前值感到困惑。“当一个字段的值取决于其先前的值时,波动性行为不一定会得到保证”是一个更合适的说法吗?感谢您通过先检查后行动的场景来解释这一点。我对波动性为何/如何依赖于变量的先前值感到困惑。“当一个字段的值取决于其先前的值时,波动性行为不一定会得到保证”是一个更合适的说法吗?在您的解释之后,这个说法似乎是模糊的。谢谢你提供的细节。经过你的解释,这个声明看起来确实很模糊。谢谢你提供的细节。