final vs volatile guaranntee w.rt to safe publication of objects

前端 未结 2 541
挽巷
挽巷 2021-02-04 02:07

From the book Java concurrency in practice :

To publish an object safely, both the reference to the object and the object\'s state must be made visibl

2条回答
  •  傲寒
    傲寒 (楼主)
    2021-02-04 02:40

    What are the the differences between bullet points 2 and 3 ?

    • volatile basically means that any writes to that field will be visible from other threads. So when you declare a field as volatile: private volatile SomeType field;, you are guaranteed that if the constructor writes to that field: field = new SomeType();, this assignment will be visible by other threads that subsequently try to read field.
    • final has quite similar semantics: you have the guarantee that if you have a final field: private final SomeType field; the write to that field (either in the declaration or in the constructor): field = new SomeType(); won't be reodered and will be visible by other threads if the object is properly published (i.e. no escape of this for example).

    Obviously, the main different is that if the field is final, you can only assign it once.

    What does he mean by final field of a properly constructed object in point 3 ?

    If, for example, you let this escape from the constructor, the guarantee provided by the final semantics is gone: an observing thread might see the field with its default value (null for an Object). If the object is properly constructed this can't happen.


    Contrived example:

    class SomeClass{
        private final SomeType field;
    
        SomeClass() {
            new Thread(new Runnable() {
                public void run() {
                    SomeType copy = field; //copy could be null
                    copy.doSomething(); //could throw NullPointerException
                }
            }).start();
            field = new SomeType();
        }
    }
    

提交回复
热议问题