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

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>