【问题标题】:Global variable changes only momentarily, is this because of simultaneous read/write?全局变量只是瞬间改变,这是因为同时读/写吗?
【发布时间】:2015-12-02 13:27:06
【问题描述】:

我有一个全局变量和多个线程,它们每隔几秒就会持续读取该变量。

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

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

这听起来是不是因为同时读/写?我在想发生了一些我不明白的事情,尽管直觉上我看不出多线程会如何改变任何事情,因为全局变量 is 至少会暂时发生变化。

除了提到的之外,没有发生任何写入。

我没有过多地阅读多线程,所以我只想要一个高级的“是的,这是可能的,并且对多线程和全局变量有意义”,我会在必要时阅读。

【问题讨论】:

  • 没有看到任何代码,任何猜测都是可能的。另外:Java 中没有全局变量。也许这就是它没有按预期执行的部分原因。您能解释一下“全局变量”的确切含义吗?
  • 类的成员变量可用于所有嵌套类
  • 如果它是一个静态成员,通过另一个实例的另一个调用会改变值
  • 答案是:是的,这对于多线程和共享变量来说是可能的并且是有意义的。多线程可能很难正确处理,所以我不会在不了解至少the basics 的情况下开始在这里和那里创建线程......例如参见:Memory consistency errors
  • @Stultuske,取决于你所说的“全球”是什么意思。 “全局变量”的一个含义是在任何地方都在范围内的变量。公共类Foo 的公共类变量bar 在任何地方都在范围内...您可以从任何地方访问它的值,即使在类Foo 之外,您也必须使用它的全名Foo.bar ,而在 Foo 类本身中,您可以只说 bar

标签: java multithreading concurrency


【解决方案1】:

没有看到实际代码我就能闻到问题所在,只需在全局静态变量前面使用volatile 即可看到神奇之处。问题解决了。

更多信息请访问Volatile vs static

【讨论】:

  • 这可能还不够。如果他使用的是 setter,那么使变量 volatile 不会有任何区别...
  • 我只是在猜测跨多线程程序访问变量时最可能发生的问题,正如@Alex 提到的No writes are happening other than the one mentioned 这意味着只发生了一次写入。
【解决方案2】:

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

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

如果你的函数声明了一个 local 变量,其名称​​隐藏全局,这就是我所期望的。

【讨论】:

  • 不,这不是问题。
  • @Alex,那么如何在您的问题中附加一些代码来演示问题?如果我们看不到您的代码,那么我们只能猜测您的问题。
  • 我已经接受了一个我只想回复你的答案。
【解决方案3】:

您应该将变量声明为 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;
        }
    }
}

【讨论】:

  • 使用完全依赖 volatile 可能会有风险,因为 volatile 可能依赖于平台。
  • Volatile 在 JLS 中定义了非常具体的语义,尽管某些平台可能会提供比规范要求的“更多安全性”,但它们不能提供更少...特别是,您的示例是 保证在没有锁的情况下是线程安全的,在所有平台上
猜你喜欢
  • 1970-01-01
  • 2019-07-24
  • 2019-08-26
  • 2023-02-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 2021-11-06
  • 1970-01-01
相关资源
最近更新 更多