Java – secure publishing when reading values in a synchronous way
My question relates to the secure publishing of field values in Java (as described here)
As far as I know, a field can be read safely (meaning that access from multiple threads will see the correct value) if:
>Read and write synchronization on the same display > field is the last > field is unstable
If I understand correctly, the following classes should not be thread safe because the initial value does not have these characteristics However, I find it hard to believe that even if I can only access from synchronous methods, I need to make the first volatile
public class Foo { private boolean needsGreeting = true; public synchronized void greet() { if (needsGreeting) { System.out.println("hello"); needsGreeting = false; } } }
Did I miss anything? Is the above code correct? If so, why? Or in this case, you must first create a volatile or use the final atomicboolean or something similar, and access it from the synchronized method
(just to clarify, I know that if the initial value is written in a synchronized method, it is thread safe even without the volatile keyword.)
Solution
There is no previous relationship between the constructor and the end of the method call, so one thread may start building the instance and making the reference available, and another thread can get the reference and start calling the greet () method Synchronization in greet () does not solve this problem
If you publish instances through the well - known double - check locking mode, it will become easier to see how If such a relationship occurs, even using dclp should be safe
public class Foo { private boolean needsGreeting = true; public synchronized void greet() { if (needsGreeting) { System.out.println("Hello."); needsGreeting = false; } } } class FooUser { private static Foo foo; public static Foo getFoo() { if (foo == null) { synchronized (FooUser.class) { if (foo == null) { foo = new Foo(); } } } return foo; } }
If more than one thread calls foosuser getFoo(). Greet (), one thread may be constructing a foo instance, but another thread may find a non empty foo reference in advance, call greet () and find that needgreeting is still false
An example (3.5) is mentioned in Java concurrency practice