First write a single case:
public class SingleDemo { private static SingleDemo s = null; private SingleDemo(){} public static SingleDemo getInstance(){ if(s == null){ s = new SingleDemo(); } return s; } }Write a test class:
public class ThreadDemo3 { public static void main(String[] args) { SingleDemo s1 = SingleDemo.getInstance(); SingleDemo s2 = SingleDemo.getInstance(); System.out.println(s2 == s2); } }The running result is always true, which means there is no problem under a single thread. Let's write a multi-thread to access the single case.
public class ThreadTest implements Runnable { //Storing singleton objects, using Set is to not store duplicate elements public Set<SingleDemo> singles = new HashSet<SingleDemo>(); @Override public void run() { //Get singleDemo s = SingleDemo.getInstance(); //Adding singleton singles.add(s); } }Use multithreaded concurrent access to singletons:
public class ThreadDemo3 { public static void main(String[] args) { // SingleDemo s1 = SingleDemo.getInstance(); // SingleDemo s2 = SingleDemo.getInstance(); // System.out.println(s2 == s2); ThreadTest t = new ThreadTest(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start(); System.out.println(t.singles); } }
The operation results are as follows:
[com.persagy.thread.SingleDemo@1bc4459, com.persagy.thread.SingleDemo@150bd4d]
or
[com.persagy.thread.SingleDemo@12b6651]
It means that there is a threaded concurrent access security issue, and the obtained instances may not be the same
How to solve thread safety problems?
Of course, the synchronization lock mechanism is used.
The following is an improvement to the singleton:
public class SingleDemo {private static SingleDemo s = null;private SingleDemo(){}public static synchronized SingleDemo getInstance(){if(s == null){s = new SingleDemo();}return s;}} The thread safety problem was solved after adding the synchronous function
Run multiple times to get the same instance, and there will be no 2 instances.
[com.persagy.thread.SingleDemo@12b6651]
However, in the case of multi-thread concurrent access, each thread must judge the lock every time it acquires an instance, which is relatively low efficiency. In order to improve efficiency, I added a double judgment method to solve the problem of efficiency
The code is as follows:
public class SingleDemo {private static SingleDemo s = null;private SingleDemo(){}public static SingleDemo getInstance(){/*If the first thread obtains the instance object of the singleton, * When the subsequent thread obtains the instance, it does not need to enter the synchronization code block. */if(s == null){//The lock used in the synchronization code block is the bytecode file object of the singleton, and this lock can only be used synchronized(SingleDemo.class){if(s == null){s = new SingleDemo();}}} return s;}}}This method solves the thread safety problem of lazy people and improves efficiency. However, in actual development, more people use hungry people. After all, this code is more complicated and complicated.
The above is the complete content of the perfect solution to the problem of lazy thread safety in single case design mode that the editor brings to you. I hope everyone will support Wulin.com more~