Person’s life is like climbing a peak, diligence is your steadfast steady feet, faith is your guide, courage is your perseverance in pursuit. Happy day arrived, may you stand on your feet, determine the direction, toward your ideal peak brave forward, do not be afraid, the future is under your feet.
As an interviewer, I would like to share with you a question THAT I often ask people over and over again. Summary of the bad place or have different views of the place welcome big private chat I discuss together.
Are you sure you know the singleton pattern?
-
Test sites are volatile and double-level
-
Whether enumerations are used
-
The “singleton pattern” is a method to ensure that only one object can be produced for a class during the operation of the system
1. The hungry
-
Implementation steps
-
Privatized constructors (to prevent new)
-
Class to create objects inside
-
Expose a static public method
-
1.1 Static Constants
// Static variable
class Sun {
// 1. Private constructor, external can new
private Sun(){}// 2. Create internal object instances of this class
private final static Sun instance = new Sun();
// 3. Provide a public static method that returns an instance object
public static Sun getInstance() {
returninstance; }}Copy the code
-
Advantages: This is a simpler way to write, which is to complete the instantiation when the class is loaded. Thread synchronization issues are avoided.
-
Disadvantages: Instantiation is done when the class is loaded, not Lazy Loading. If the instance is never used, then memory is wasted
-
However, instance is instantiated when the class is loaded. In singleton mode, most instances call getInstance. However, there are many reasons for class loading. Therefore, there is no other way (or other static method) to load the class, in which case instance initialization does not achieve the effect of lazy loading
-
Conclusion: This singleton pattern is available and may cause memory waste
1.2 Static code blocks
// Static variable
class Sun {
// 1. Private constructor, external can new
private Sun(){}//2. This class internally creates object instances in the Silicon Valley Java design pattern
private static Sun instance;
static { // In a static code block, create a singleton object
instance = new Sun();
}
// 3. Provide a public static method that returns an instance object
public static Sun getInstance() {
returninstance; }}Copy the code
Advantages and disadvantages are the same as above:
-
This method is similar to the above method, except that the class instantiation process is placed in the static code block, and when the class is loaded, the code in the static code block is executed to initialize the instance of the class.
-
Conclusion: This singleton pattern works, but it can be a waste of memory
2. LanHanShi
2.1 Threads are unsafe
/ / LanHanShi
class Sun {
// 1. Private constructor, external can new
private Sun(){}// 2. Declare only object instances
private final static Sun instance;
// 3. Provide a static public method and create instance only when the method is used
public static Sun getInstance() {
if(instance == null) {
instance = new Sun();
}
returninstance; }}Copy the code
-
Advantages: Provides a Lazy Loading effect, but can only be used in a single thread.
-
Disadvantages: In multithreading, if one thread enters an if (instance == null) statement and another thread passes the statement before it can proceed, multiple instances can be created. Therefore, this approach cannot be used in multithreaded environments
-
Conclusion: In real development, don’t use this approach
2.2 Thread safety, synchronous method
/ / LanHanShi
class Sun {
// 1. Private constructor, external can new
private Sun(){}// 2. Declare only object instances
private final static Sun instance;
// 3. Provide a static public method, add synchronous processing code, solve the thread safety problem
public static synchronized Sun getInstance() {
if(instance == null) {
instance = new Sun();
}
returninstance; }}Copy the code
-
Advantages: Solves thread safety issues
-
Disadvantages: Inefficient in that every thread that wants to get an instance of a class needs to execute the getInstance() method in synchronization. If you want to get an instance of the class, return it. Method synchronization efficiency is too low
-
Conclusion: In real development, this approach is not recommended
2.3 Thread safety, synchronized code blocks
/ / LanHanShi
class Sun {
// 1. Private constructor, external can new
private Sun(){}// 2. Declare only object instances
private final static Sun instance;
// 3. Provide a static public method, add synchronous processing code, solve the thread safety problem
public static Sun getInstance() {
if(instance == null) {
synchronized(Sun.class){}
instance = newSun(); }}returninstance; }}Copy the code
- Not recommended for the same reason
2.4 DCL
- Double Check Lock: Double Check Lock
/ / LanHanShi
class Sun {
// 1. Private constructor, external can new
private Sun(){}// 2. Declare only object instances
private final static Sun instance;
// 3. Provide a static public method with double checking code to solve thread safety problems and lazy loading problems
public static Sun getInstance() {
if(instance == null) {
synchronized(Sun.class){
if(instance == null) {
instance = newSun(); }}}returninstance; }}Copy the code
-
The concept of double-check is commonly used in multi-threaded development. As shown in the code, we perform two if (instance == null) checks to ensure thread safety.
-
If (singleton == null), return the instantiated object directly, and avoid repeated method synchronization.
-
Thread safety; Lazy loading; High efficiency
-
Conclusion: This singleton design pattern is recommended for real-world development, and is perfect with the volatile keyword
2.5 Static inner Classes
// Static inner class completion is recommended
class Sun {
private static volatile Sun instance;
// Privatize the constructor
private Sun() {}
// Write a static inner class with a static attribute Singleton
private static class SunInstance {
private static final Sun INSTANCE = new Sun();
}
/ / to provide a public static method, direct return SingletonInstance. The INSTANCE
public static synchronized Sun getInstance() {
returnSunInstance.INSTANCE; }}Copy the code
-
This approach uses a classloading mechanism to ensure that only one thread initializes the instance
-
The static inner class method is not instantiated immediately when the Sun class is loaded. Instead, the SunInstance class is loaded when it needs to be instantiated by calling the getInstance method.
-
The static properties of a class are initialized only when the class is first loaded, so the JVM helps us keep our threads safe from entering while the class is initialized.
-
Advantages: avoid thread insecurity, use static internal class characteristics to achieve delay loading, high efficiency
-
Conclusion: Recommended use.
2.6 Enumerating singletons
class Fire{
}
public enum Sun {
INSTANCE;
private Fire instance;
private Sun() {
instance = new Fire();
}
public Fire getInstance() {
return instance;
}
}
public class TestEnumInstance {
public static void main(String[] args){ Fire f1 = Sun.INSTANCE.getInstance(); Fire f2 = Sun.INSTANCE.getInstance(); System.out.println(f1 == f2); System.out.println(f1.hashCode() == f2.hashCode()); }}Copy the code
-
The above class Fire is the resource to which we apply the singleton pattern, in the form of network connections, database connections, thread pools, and so on.
-
The way to get the resource is simple: just sun.instance.getInstance () gets the INSTANCE you want.
-
Let’s look at how singletons are guaranteed:
-
First, we make it clear in enumerations that the constructor is limited to private, that the constructor is executed when we access an enumeration instance, and that each enumeration instance is of static final type, meaning that it can only be instantiated once. When the constructor is called, our singleton is instantiated.
-
That is, because instances in enum are guaranteed to be instantiated only once, our INSTANCE is guaranteed to be instantiated once.
-
-
As you can see, enumeration singletons are relatively simple to implement. Let’s look at the Enum class declaration:
public abstract class Enum>
implements Comparable.Serializable
Copy the code
-
Enumerations provide a serialization mechanism. Implement the singleton pattern with the help of enumerations added in JDK1.5. Not only do you avoid multithreaded synchronization problems, but you also prevent deserialization from recreating new objects
-
This approach is advocated by Josh Bloch, author of Effective Java.
Enumerated types of single elements have become the best way to implement Singleton.Copy the code
Matters needing attention
-
The singleton mode ensures that only one object of this class exists in the system memory, saving system resources. For some objects that need to be created and destroyed frequently, the singleton mode can improve system performance
-
When instantiating a singleton class, you must remember to use the corresponding method to get the object instead of using new
-
Scenarios where the singleton pattern is used: objects that need to be created and destroyed frequently, objects that take too much time or consume too much resources to create (i.e., heavyweight objects) but are frequently used, tool class objects, objects that frequently access databases or files (such as data sources, session factories, etc.)
welfare
Massive Internet big factory interview real question detailed solution to share with you, common learning. Career planning, resume guidance, Java practical books, various Java learning videos, skills learning, thinking training.
Interested partners can pay attention to my nuggets account, private chat to get a class of information.
Bonus 1:10G development related ebook, there is always a suitable for you, private chat access
Bonus 2:60K resume template for successful employment