Domanda

I have this simple piece of code.

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;
    }
}

It outputs what I'd expect:

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

The strange thing is the a=a in zzz(). It doesn't seem to change anything when I take it out. Why is it there?

È stato utile?

Soluzione

The only reason I can think of is that the person who wrote that code understood that only the array is volatile but not its content and added a = a to enforce visibility of the writes performed on the array items.

It doesn't seem to change anything when I take it out.

The fact that it still works on your machine with your JVM does not mean that it would work on another machine with a different JVM. In theory, removing the a = a; statement could lead to a never-ending while loop.


Side note

I would have thought that the Java Memory Model (JMM) could allow a JVM to ignore that statement, the same way that a synchronized(new Object()) can be ignored.

It seems however that it is not the case*:

You may have noticed that I did provide a way of getting a volatile write above with just arrays: by writing out a self-reference.

*Jeremy Manson is one of the authors of the JMM.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top