What is a publishing object?
A publishing object is an object that can be used by code outside the current scope
What is Object escaping?
Object escaping is a false release, meaning that when an object is not yet constructed, it is seen by other threads
Escape-demo
@Slf4jpublic class Escape { private int thiscanbeescape = 0; Public Escape () { new Innerclass (); } Private class innerclass{public innerclass () { log.info ("{}", Escape.this.thisCanBeEscape); } } public static void Main (string[] args) { new Escape ()} }
In this instance, the escape object has not been constructed yet, accessing the object's member variable Thiscanbeescape, which is thread insecure and highly deprecated.
Unsafe release-demo
@Slf4jpublic class Unsafepublish { private string[] states = {"A", "B", "C"}; Public string[] GetStates () { return states; } public static void Main (string[] args) { unsafepublish unsafepublish = new Unsafepublish (); Log.info ("{}", Arrays.tostring (Unsafepublish.getstates ())); Unsafepublish.getstates () [0] = "D"; Log.info ("{}", Arrays.tostring (Unsafepublish.getstates ()));} }
The output is: [A,b,c] and [D,b,c] The published object is thread insecure because there is no guarantee that other threads will modify the states domain, resulting in a state error
Four ways to safely publish objects:
A, initializing an object reference in a static initialization function
B. Save the object's reference to a volatile type field or to a Atomicreference object
C, save the object's reference to the final type field of a properly constructed object
D. Save the object's reference to a lock-protected domain
How to safely publish an object?
We explain how to safely publish objects by implementing different singleton
Single Case-demo1
public class SingletonExample1 { //private constructor SingletonExample1 () { }// Singleton object private static SingletonExample1 instance = null; Static Factory method Public static SingletonExample1 getinstance () { //single thread No problem, multi-threaded when the problem occurs if (instance = = null) { instance = new SingletonExample1 (); } return instance;} }
This instance does not have any problems in single-threaded mode, but in multithreaded mode, such as two threads running simultaneously to judge Instance==null, it is possible to new out two instances, so it is thread insecure, this is the lazy mode, this instance satisfies the a condition, if plus the D condition, When you determine whether NULL is locked, you can become thread-safe
Single Case-demo2
public class SingletonExample2 { ///A Hungry man mode is insufficient, if there is too much processing in the constructor method, it will cause the class to load particularly slow //private Constructors SingletonExample2 () { } //Singleton object private static SingletonExample2 instance = new SingletonExample2 (); Static Factory method Public static SingletonExample2 getinstance () { return instance; }}
This demo is thread-safe, you need to be aware of two points when using a hungry man mode, one is that this class must be used (to avoid wasting resources), and the other is that there is not too much processing in the private construction method 4
Single Case-demo3
public class SingletonExample3 { //private constructor SingletonExample3 () { }// Singleton object Private static SINGLETONEXAMPLE3 instance = null; Static Factory method public static synchronized SingletonExample3 getinstance () { //single thread No problem, multi-threaded when the problem occurs if ( instance = = null) { instance = new SingletonExample3 (); } return instance;} }
This demo is a demo1 lock case, is thread-safe, but it is not recommended, because this ensures thread safety, but there is a certain overhead in performance
Single Case-demo4
/** * Lazy mode double Synchronous lock Singleton mode * Single instance created on first use * Double detection mechanism is not necessarily thread safe because there is a command reflow exists */public class SingletonExample4 { //private constructor pri Vate SingletonExample4 () { } //Singleton object private static SingletonExample4 instance = null; Static Factory method Public static SingletonExample4 getinstance () { //single thread No problem, multi-threaded when the problem occurs if (instance = = NULL) { //dual detection mechanism //sync lock synchronized (singletonexample4.class) { if (instance = = null) { Instance = new SingletonExample4 ();}} } return instance;} }
This demo is an optimized version of Lazy mode, but note that this demo is not thread safe because there is a command reflow, and when the Instance=new SingletonExample4 () is executed, the CPU performs a three-step operation: 1, Memory=allocate () Allocating an object's memory space 2, ctorinstance () initialization object 3, instance = Memory Setting instance points to the newly allocated RAM, but due to JVM and CPU optimizations, the command reflow occurs, such as the result of the rearrangement becomes 1. 3,2, in the case of single-threaded, there is no problem, but in the case of multithreading can be problematic, if at this time a thread execution to instance=new SingletonExample4 (), a command reflow occurred, executed to the second step of 3, At this point, instance has executed the object's memory, but the object has not been initialized, if at this point the B thread executes to if (Instance==null), at this time the condition is not established, direct return, because this object has not been initialized, A problem can occur if you use this object directly.
Single Case-demo5
/** * Lazy mode double Synchronous lock Singleton mode * Single instance created on first use * Double detection mechanism is not necessarily thread safe because there is a command reflow exists */public class SingletonExample5 { //private constructor pri Vate SingletonExample5 () { } //1, Memory = allocate () allocates the object's RAM space //2, Ctorinstance () initialization object //3, Instance = Memeory Set instance points to the memory that is just allocated //the volatile and double-detection mechanisms restrict command rearrangement, which limits the write operation of the Code //Singleton object, REDIRECT private volatile static SingletonExample5 instance = NULL with volatile limit code occurrence instruction; Static Factory method Public static SingletonExample5 getinstance () { //single thread No problem, multi-threaded when the problem occurs if (instance = = null) { //Dual detection mechanism //sync lock synchronized (singletonexample5.class) { if (instance = = null) { instance = New SingletonExample5 (); }}} return instance;} }
This demo is an upgrade version of Demo4, as long as the problem of the command reflow, in the previous blog "Thread Security" we have described volatile can limit the code to take place command Reflow, this demo is thread-safe.
Single Case-demo6
/** * A hungry man mode * Singleton instances are created when class is loaded */@ThreadSafepublic class SingletonExample6 { //A hungry man mode is insufficient, if there is too much processing in the construction method, it will cause the class to load very slowly / /private constructor Private SingletonExample6 () { } // initialization of a static domain for a singleton object private static SingletonExample6 instance = null; Static block mode static { instance = new SingletonExample6 (); } Static Factory method Public static SingletonExample6 getinstance () { return instance; } public static void Main (string[] args) { System.out.println (getinstance (). Hashcode ()); System.out.println (getinstance (). Hashcode ());} }
Demo2 is the static code domain of the A Hungry Man mode, this demo is the static code block mode of a hungry man pattern, this demo is also thread-safe
Single Case-demo7
/** * Enumeration mode: safest * Compared to the lazy mode in terms of security easier to guarantee * compared to the A Hungry man mode is actually called when the initial initialization is done */public class SingletonExample7 { private singletone Xample7 () { } //Static factory method public static SingletonExample7 getinstance () { return Singleton.INSTANCE.getSingleton (); } Private enum singleton{ INSTANCE; Private SingletonExample7 Singleton; The JVM guarantees that this method is only called once, and is the Singleton () { Singleton = new SingletonExample7 () initialized before the class call; } Public SingletonExample7 Getsingleton () { return singleton;}} }
This demo is our most recommended single example, and is thread-safe, it is more secure than the lazy mode in terms of security, compared to the A Hungry man mode is actually called when the initial initialization
Knowledge of Java is a lot to understand. (Forward as below)