"Publish (Publish)" an object that means that the object can be used in code outside the scope.
For example:
Save a reference to the object to a place where other code can access it
Returns the reference in a non-private method
To pass a reference to a method in another class
Sometimes it is necessary to make sure that the object and its internal state are not published, but in some cases it needs to be published.
If you want to ensure thread safety at the time of publishing, you may need to synchronize.
Publishing internal states can break encapsulation and make it difficult for programs to maintain immutability conditions.
For example, publishing the object before the object construction is complete destroys thread security.
This is called "escaping" when an object that should not be published is published.
Examples of escaping:
Public class Publishdemo { publicstatic set<integer> intset; Public void Initialize () { new hashset<>(); }}
When you publish an object, other objects may be published indirectly. For example, not only the set in the above code will be published, but the integer object in the set will also be published.
Public class unsafestates { privatenew string[] {"AK", "K"}; Public string[] GetStates () { return states; }}
In short, is a person can handle the matter, now make more than n people can plug in a hand, you said security is not safe. When an object escapes, it must be assumed that a class or thread will misuse the object. This is why encapsulation is required: encapsulation makes it possible to analyze the correctness of a program and makes it harder to inadvertently break design constraints.
Another mechanism for publishing an object or its internal state is to publish an internal instance of the class.
Public classPublishinnerclass { PublicPublishinnerclass (EventSource source) {Source.registerlistener (NewEventListener () { Public voidonEvent (Event e) {System.out.println ("Heheda"); } } ); } classEventSource { Public voidRegisterlistener (EventListener eventlistener) {//it's exposed. } }}
Do not let this escape during the construction process.
A common mistake in making this reference escape during construction is to start a thread in the constructor. When an object creates a thread in its constructor, whether it is explicitly created (by passing it to the constructor) or implicitly created (because thread or runnable is an inner class of the object), the This reference is shared by the newly created thread.
The new thread can see her until the object has been fully constructed. Creating a thread in the constructor is not an error, but it is best not to start it immediately, but to start with a start or Initialize method. When you invoke a Rewritable instance method in a constructor (neither private nor finalization), this reference is also caused to escape during the construction process.
New skills
If you want to register an event listener or a startup thread in a constructor, you can avoid improper construction by using a private constructor and a common factory method (Factory).
Public classSafelistener {Private FinalEventListener Listener; PrivateSafelistener () {Listener=NewEventListener () { Public voidonEvent (Event e) {System.out.println ("Good"); } }; } classEventSource { Public voidRegisterlistener (EventListener listener) {}} Public StaticSafelistener newinstance (EventSource source) {Safelistener safe=NewSafelistener (); Source.registerlistener (Safe.listener); returnsafe; }}
Conclusion One: When a registered event listener hears an event occurring, a new thread is enabled to perform the related thing. (This we manually started a thread in the code simulation, when no listener registration, the boot thread will automatically block!) )
Conclusion Two: When an object of an inner class is initialized externally, the object of this inner class retains a reference to an outer object. This is a mechanism that comes with Java, which is called "synthetic" in Java. We can clearly see this implementation by debugging breakpoints.
Java Concurrent Programming (vi) release and escape