【问题标题】:Assigning the value of an array variable to itself?将数组变量的值分配给自身?
【发布时间】:2013-06-26 18:04:06
【问题描述】:

我有这段简单的代码。

class A {
    static volatile String[] a = new String[9];

    public static void main(String[] args) {
        new Thread() {
            public void run() {
                for (int i = 0; i < a.length; i++) {
                    while (a[i] == null);
                    System.out.println(a[i]);
                }
            }
        }.start();

        a[0] = "The";
        zzz();
        a[1] = "quick";
        zzz();
        a[2] = "brown​";
        zzz();
        a[3] = "fox";
        zzz();
        a[4] = "jumped";
        zzz();
        a[5] = "over";
        zzz();
        a[6] = "the";
        zzz();
        a[7] = "lazy";
        zzz();
        a[8] = "cat";
        zzz();
    }

    public static void zzz() {
        try {
            Thread.sleep(300);
        } catch (Exception e) {}
        a=a;
    }
}

它输出我所期望的:

$ javac A.java && java A
The
quick
brown​
fox
jumped
over
the
lazy
cat

奇怪的是zzz() 中的a=a。当我拿出它时,它似乎没有任何改变。为什么会在那里?

【问题讨论】:

  • 它什么也没做。它可能留在那里添加断点。
  • 分配给 volitle 是否会发布给其他线程?

标签: java concurrency volatile memory-visibility


【解决方案1】:

我能想到的唯一原因是编写该代码的人明白只有数组是易失性的,而不是其内容,并添加了a = a 以强制对数组项执行的写入可见。

当我拿出它时,它似乎没有任何改变。

它仍然可以在装有 JVM 的机器上运行这一事实并不意味着它可以在具有不同 JVM 的另一台机器上运行。从理论上讲,删除a = a; 语句可能会导致一个永无止境的while 循环。


旁注

我原以为 Java 内存模型 (JMM) 可以允许 JVM 忽略该语句,就像可以忽略 synchronized(new Object()) 一样。

不过似乎it is not the case*:

您可能已经注意到,我确实提供了一种仅使用数组来获取上述 volatile 写入的方法:通过写出自引用

*Jeremy Manson 是 JMM 的作者之一。

【讨论】:

  • 我正在考虑你的最后一部分,虽然我很好奇删除像 volatile 变量这样的死代码的规则。
  • @JohnVint 似乎不是这样 - 更新。
  • 是+1,我在博客中找到的最重要的部分是This definitely does provide the volatile write. However, what good does it do you? The virtue of a volatile write is that a corresponding read can detect that it happened, and do something based on the new value.
  • @JohnVint 在操作代码中我​​们两者都有,所以程序不能有无限循环。
猜你喜欢
  • 1970-01-01
  • 2015-10-03
  • 1970-01-01
  • 2014-03-27
  • 2016-12-12
  • 2020-07-27
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
相关资源
最近更新 更多