9

Java concurrency in practice book has given an example for unsafe publication

public class Holder 
{
    private int n;
    public Holder(int n)
    {
        this.n = n; 
    }
    public void assertSanity() 
    {
        if (n != n)
            throw new AssertionError("This statement is false.");
    }
}

The above code seems to be thread safe. It would not be thread safe if n is public variable. Is the book example wrong?

4

3 回答 3

10

Safe publication is about memory visibility. The concept of memory visibility is a bit trickier than other thread safety issues such as race conditions.

Memory visibility issues arise when actions performed by one thread in certain order appear to be performed in different order for another thread (it may be caused by optimizations made by compiler or CPU).

In your case:

// Thread A
h = new Holder(42);

// Thread B
h.assertSanity();

For Thread A, n is certainly initialized before h.

But in absense of safe publication it's not guaranteed to be the same for Thread B. Thread B may see h in initialized state, but n won't be initialzed yet. Moreover, the state of n as observed by Thread B may change during evaluation of n != n, causing assertSanity() to throw an exception.

Note that this problem is not something that is guaranteed to happen in all cases. You will probably never see this happening, but Java Memory Model doesn't guarantee correctness in this case nonetheless.

于 2013-09-04T16:06:24.413 回答
2

It's not thread safe, because when the object of the class is created Holder.n is assigned a default value of 0.

Because of that, some threads can see the value 0 and others the value n that is passed to constructor.

于 2013-09-04T16:02:37.230 回答
0

This class is fine. We should usually expect that objects are shared between threads only through safe publication. In that case Holder.n will appear to be the same constant value for any observers.

Sharing objects through unsafe publication is sometimes justifiable, however the programmer must be responsible to make certain that the object can be used in that situation, e.g. String.

Most classes do not need to, and should not, be designed to work with unsafe publication.

于 2013-09-04T16:13:20.217 回答