gpt4 book ai didi

java - Java中的 volatile 与静态

转载 作者:bug小助手 更新时间:2023-10-28 10:39:39 27 4
gpt4 key购买 nike

static 表示所有对象的值的一份副本,volatile 表示所有线程的值的一份副本是否正确?

反正static变量值也将是所有线程的一个值,那我们为什么要选择volatile

最佳答案

在Java中声明一个static变量,意味着无论创建多少类对象,都只会有一个副本。即使根本没有创建 Objects,也可以访问该变量。但是,线程可能有它的本地缓存值。

当变量是volatile而不是static时,每个Object都会有一个变量。所以,表面上看起来与普通变量没有区别,但与静态完全不同。但是,即使有 Object 字段,线程也可以在本地缓存变量值。

这意味着如果两个线程同时更新同一个 Object 的变量,并且该变量未声明为 volatile,则可能存在其中一个线程缓存旧值的情况。

即使您通过多个线程访问 静态 值,每个线程也可以拥有其本地缓存副本!为避免这种情况,您可以将变量声明为 static volatile,这将强制线程每次读取全局值。

但是,volatile 不能代替正确的同步!
例如:

private static volatile int counter = 0;

private void concurrentMethodWrong() {
counter = counter + 5;
//do something
counter = counter - 5;
}

多次并发执行concurrentMethodWrong可能导致counter的最终值不为零!
要解决这个问题,你必须实现一个锁:

private static final Object counterLock = new Object();

private static volatile int counter = 0;

private void concurrentMethodRight() {
synchronized (counterLock) {
counter = counter + 5;
}
//do something
synchronized (counterLock) {
counter = counter - 5;
}
}

或使用 AtomicInteger类。

关于java - Java中的 volatile 与静态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2423622/

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