0

I'm reading The Java® Language Specification Java SE 8 Edition and at 17.5. final Field Semantics there is an Example 17.5-1. final Fields In The Java Memory Model(https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5).

class FinalFieldExample { 
    final int x;
    int y; 
    static FinalFieldExample f;

    public FinalFieldExample() {
        x = 3; 
        y = 4; 
    } 

    static void writer() {
        f = new FinalFieldExample();
    } 

    static void reader() {
        if (f != null) {
            int i = f.x;  // guaranteed to see 3  
            int j = f.y;  // could see 0
        } 
    } 
}

Description states:

One thread might execute the method writer and another might execute the method reader. Because the writer method writes f after the object's constructor finishes, the reader method will be guaranteed to see the properly initialized value for f.x: it will read the value 3. However, f.y is not final; the reader method is therefore not guaranteed to see the value 4 for it.

I write some code with two threads that reproduce this situation but I can't obtain case when reader method is return anything else than 4? There is constructor that always set f.y to 4.

Maybe I can't understand something. I will be thankful to clarifying that.

EDIT Thanks all, specially assylias. Testing initialization safety of final fields explained to me completely. For me these sentences is most important:

From Java 5.0, you are guarenteed that all threads will see the final state set by the constructor.

in practice is to ensure that the constructor finishes before any subsequent program actions take place

Community
  • 1
  • 1
kciejek
  • 9
  • 3
  • The fact that 0 is a valid outcome does not mean that your specific JVM/OS/CPU combination can produce that outcome. In particular I don't think you could create that situation on hotspot/x86. – assylias Oct 22 '15 at 08:23
  • This is the "official" answer, by Jeremy Manson: http://stackoverflow.com/a/15517168/829571 – assylias Oct 22 '15 at 08:26

1 Answers1

0

In general it is difficult to obtain all possibilities with multithreaded applications (especially if caching is involved). It is not even always possible to get all possible results on all JVMs or OSes or CPUs.

Suppose the following: Thread 1: creates f with the writer method. Thread 2: calls reader().

Why can the reader see f non null and f.y different from 4? The answer is, that local caching could be used to optimize the code. Than f is created, but the value of y is not yet changed.

Edit: The "official" answer, by Jeremy Manson can be found here. (thanks to assylias' comment)

Community
  • 1
  • 1
Burkhard
  • 14,596
  • 22
  • 87
  • 108