Java: Safe to “leak” this-reference in constructor for final class via _happens-before_ relation?

前端 未结 1 1139
广开言路
广开言路 2021-02-05 14:18

Section 3.2.1 of Goetz\'s \"Java Concurrency in Practice\" contains the following rule:

Do not allow the this reference to escape during con

1条回答
  •  鱼传尺愫
    2021-02-05 14:31

    You are correct. In general, Java memory model does not treat constructors in any special way. Publishing an object reference before or after a constructor exit makes very little difference.

    The only exception is, of course, regarding final fields. The exit of a constructor where a final field is written to defines a "freeze" action on the field; if this is published after the freeze, even without happens-before edges, other threads will read the field properly initialized; but not if this is published before the freeze.

    Interestingly, if there is constructor chaining, freeze is defined on the smallest scope; e.g.

    -- class Bar
    
    final int x;
    
    Bar(int x, int ignore)
    {
        this.x = x;  // assign to final
    }  // [f] freeze action on this.x
    
    public Bar(int x)
    { 
        this(x, 0);
        // [f] is reached!
        leak(this); 
    }
    

    Here leak(this) is safe w.r.t. this.x.

    See my other answer for more details on final fields.


    If final seems too complicated, it is. My advice is -- forget it! Do not ever rely on final field semantics to publish unsafely. If you program is properly synchronized, you don't need to worry about final fields or their delicate semantics. Unfortunately, the current climate is to push final fields as much as possible, creating an undue pressure on programmers.

    0 讨论(0)
提交回复
热议问题