身在此山中,云深不知处:Publication and Escape

来源:百度文库 编辑:九乡新闻网 时间:2024/04/30 09:46:44
What is escape?
Escape means when a Object is be constructing, before it have been finish constructed, it's reference already published to code outside.
this will make unsafe thread problem when use multithreads.

1. the common used way for published object.
public static Set knownSecrets;public void initialize() {knownSecrets = new HashSet();}
any Secret object add to the konwSecrets have been published.
But is this way a escape?
I don't think this is escape. if it don't violate the principle above mentioned.

2. Allowing Internal Mutable State to Escape. Don't Do this.


class UnsafeStates {            private String[] states = new String[] {            "AK", "AL" ...            };            public String[] getStates() { return states; }            }            

the problem is the variable array of states is private, but there have a public getStates() method, it expose the private variable outside,
that means it violate the intends scope of private, it actual a public variable now.

3. escape out this reference by inner class

Implicitly Allowing the this Reference to Escape. Don't Do this.


public class ThisEscape {
private int outThis;

class InnerClass {

private int innerThis;

public void getOutThis(){
//inner class can obtain the outer class this reference, and can access the private variable in the outer class
//other way like implement interface or extend can't have this available, this is the special only for inner class
ThisEscape.this.outThis = 2;
this.innerThis = 3;
}
}
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
//because inner class owner the outer class this reference, the outer this has already escape by the
//inner class published, so it's not safe for thread
public void onEvent(Event e) {
doSomething(e);
}
});
}

}

Inner class can obtain the outer class this reference, and can access the private variable in the outer class,
other way like implement interface or extend can't have this available, this is the special only for inner class

Do not allow the this reference to escape during construction.



solution for protect:
Using a Factory Method to Prevent the this Reference from Escaping During Construction.

public class SafeListener {                        private final EventListener listener;                        private SafeListener() {                        listener = new EventListener() {                        public void onEvent(Event e) {                        doSomething(e);                        }                        };                        }                        public static SafeListener newInstance(EventSource source) {                        SafeListener safe = new SafeListener();                        source.registerListener(safe.listener);                        return safe;                        }                        }                        


when use factory method, that means the protect object(SafeListener) already been constructed. the inner class EventListener have no chance
to publish the outer this reference before it haven't been constructed. so use factory method will avoid this way escape by inner class.