There is a class:

public class A { public int f; public A() { f = 42; } } 

which is used by two threads:

 class Thread1 { private A a; Thread1(A a) { this.a = a; } public void run() { a = new A(); } } 

and second:

 class Thread2 { private A a; Thread1(A a) { this.a = a; } public void run() { if (a != null) { System.out.print(af); } } } 

If you run two streams, passing in them a link to object A , then there will be one of the four scenarios:

1) prints 42 if the thread has read the field from the initialized object;

2) does not print anything if the object is null and the thread saw it;

3) prints 0 if the first thread started initializing the object, and the second one entered at the moment when it did not execute new A () in the first thread;

4) NullPointerException - if you are unlucky and in the race for reading, first a! = Null , and then the field is asked for a = null

But if in the second stream to copy a global variable to a local one, then NPE will not be:

 class Thread2 { private A a; Thread1(A a) { this.a = a; } public void run() { A anotherA = a; if (anotherA != null) { System.out.print(anotherA.f); } } } 

Why?

Each thread has its own copy of local variables - but how does this affect the publication?

  • Hm And where is your global variable? Thread2 will only change its local copy. - VladD

1 answer 1

First of all, as @VladD correctly noted, you do not have a global variable. Secondly, you do not copy a variable, but simply create another link to it. Thirdly, in the first stream you rewrite the value of the reference a , and now this link points to a new instance of the object, which is enclosed only in this stream.

And fourthly, where is the safe publication here?