Java 全局变量只是暂时改变,这是因为同时读/写吗?

Java 全局变量只是暂时改变,这是因为同时读/写吗?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有一个全局变量和多个线程,这些线程每隔几秒钟就一致地读取变量 现在我在一个线程中有一个写入变量的方法,当我在写入它的函数中打印出全局变量时,我看到写入已经发生,并且变量值根据需要更改 但是当我在函数执行后立即从函数范围外读取时,全局变量实际上没有改变,写入也没有成功 这听起来像是由于同时读/写造成的吗?我认为有一些事情我不明白,尽管直觉上我看不出多线程会如何改变任何事情,因为全局变量至少是暂时改变的 除上述情况外,未发生任何写入操作 我没有读过太多关于多线程的内容,所以我只想要一个高层次的“是

我有一个全局变量和多个线程,这些线程每隔几秒钟就一致地读取变量

现在我在一个线程中有一个写入变量的方法,当我在写入它的函数中打印出全局变量时,我看到写入已经发生,并且变量值根据需要更改

但是当我在函数执行后立即从函数范围外读取时,全局变量实际上没有改变,写入也没有成功

这听起来像是由于同时读/写造成的吗?我认为有一些事情我不明白,尽管直觉上我看不出多线程会如何改变任何事情,因为全局变量至少是暂时改变的

除上述情况外,未发生任何写入操作


我没有读过太多关于多线程的内容,所以我只想要一个高层次的“是的,这是可能的,并且对多线程和全局变量有意义”,我会根据需要进行阅读。

在没有看到实际代码的情况下,我可以嗅到问题,只要在全局静态变量前面使用
volatile
,就可以看到它的神奇之处。问题解决了


有关更多信息,请访问

您应该将变量声明为volatile,并同步对它的访问。下面的代码是一个示例,用于防止访问myVariable的线程之间发生冲突

public class ChangeVariable {
    static volatile int myVariable;
    static final Object lock = new Object();

    public static void setVariable(int value) {
        synchronized (lock) {
            myVariable = value;
        }
    }

    public static int getVariable() {
        synchronized (lock) {
            return myVariable;
        }
    }
}

您确定没有两个同名的变量吗

我在写的函数中打印出全局变量,我看到写已经发生了…但是当我从范围外读取时。。。全局变量实际上没有改变


如果您的函数声明了一个局部变量,其名称会影响全局变量,那么这就是我所期望的。

在没有看到任何代码的情况下,任何猜测都是可能的。另外:Java中没有全局变量。也许这就是为什么它不能像你期望的那样运行的部分原因。你能解释一下“全局变量”的确切含义吗?一个类的成员变量可用于所有嵌套类如果它是静态成员,通过另一个实例的另一次调用会改变值答案是:是的,这是可能的,并且对多线程和共享变量有意义。多线程处理可能很难做到正确,所以我不会在不了解至少。。。参见示例:.@Stultuske,取决于您所说的“全球”是什么意思。“全局变量”的一个含义是一个在任何地方都适用的变量。公共类
Foo
的公共类变量
bar
无处不在。。。您可以从任何地方访问它的值,即使在类
Foo
之外,您也必须使用它的全名
Foo.bar
,而在
Foo
类本身中,您可以只说
bar
。这可能还不够。如果他使用的是setter,那么将变量设置为volatile不会有任何区别……我只是猜测在跨多线程程序访问变量时最可能出现的问题,正如@Alex所提到的
除了所提到的
之外,没有写入发生,这意味着只发生了一次写入。使用完全依赖volatile可能有风险,因为volatile可能依赖于平台。volatile在JLS中定义了非常具体的语义,尽管某些平台可能提供比规范要求的“更多安全性”,但它们不能提供更少的安全性。。。特别是,您的示例在所有平台上都保证是线程安全的,没有锁。不,这不是问题所在。@Alex,那么在您的问题上附加一些代码来演示问题如何?如果我们看不到你的代码,那么我们只能猜测你的问题。我已经接受了一个答案,我只是想回应你。