Singleton mode is the simplest of the 23 GOF modes, and it is also the most frequently appeared one of the design modes, and it is also the most frequently used by interviewers. Why? Because singletons are simple enough to write a singletons code in a few minutes, interviewers often choose singletons as questions in design patterns. Let’s break down the singleton model into a few points. Where can the interviewer test you?
Significance of the singleton pattern
Often the interviewer will ask you in general terms, what is the singleton pattern? What pain points are singletons used to address? What would we do without the singleton pattern? Does the singleton pattern have any disadvantages?
One of the simplest design patterns, the singleton pattern is the creation pattern, which provides a way to create objects, ensuring that only a single object is created. The main purpose of this design pattern is that only one instance of a class can occur in the entire system, that is, each class has only one object. The pain point of the singleton pattern is to save resources and time from two aspects:
1. Because of frequently used objects, you can eliminate the time spent creating objects, which is important for heavyweight objects.
2. Because we don’t need to create objects frequently, our GC pressure is reduced, and we have STW(Stop the world) in GC, which saves the time of the singleton pattern in this aspect: The simple singleton pattern design and development are relatively simple, but the complex singleton pattern needs to consider concurrency issues such as thread safety, which introduces some complexity.
Expand: What can you expand from your answer? When we talk about GC, we will probably ask you about GC, STW, etc. When talking about the disadvantages of the complex singleton pattern, this time may ask you to design a good singleton pattern how would you design, how would you implement?
Design of singleton pattern
Usually, the interviewer will ask you how do you design the singleton? What do you look for? What are the general implementations of the singleton pattern?
There are several factors to consider when designing a singleton pattern:
– Thread safety – lazy loading – Code safety: such as protection against serialization attacks, protection against reflection attacks (preventing reflection from making private method calls) – Performance factors
Generally speaking, there are about 7 or 8 implementations in Baidu. Here are some of the most important ones to know: hungry, lazy (thread-safe, thread-unsafe), double-checking (DCL), inner classes, and enumeration (key).
|
Thread safety |
Good concurrency performance |
You can lazily load |
Serialization/deserialization security |
Can resist reflex attacks |
|
---|---|---|---|---|---|---|
The hungry type |
Y |
Y |
|
|
|
|
LanHanShi |
Don’t lock |
|
Y |
Y |
|
|
The lock |
Y |
|
Y |
|
|
|
DCL |
Y |
Y |
Y |
|
|
|
Static inner class |
Y |
Y |
Y |
|
|
|
The enumeration |
Y |
Y |
|
Y |
Y |
Extension: When we talked about the implementation of each pattern, you will probably be asked to write the code for each pattern by hand. You may also be asked about thread safety, code safety, etc.
The hungry mode
The code for hungry Man mode is as follows:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance() {returninstance; }}Copy the code
The code for hanhan-mode is relatively simple. Objects are defined as private static in the class, with getInstance(), which ensures that singletons are unique through Java’s classLoader mechanism. Extension:
When is instance initialized?
The Singleton class is initialized as soon as it is loaded. The Java Virtual Machine specification does not enforce when to start the class loading process, but for class initialization, the VIRTUAL machine specification strictly specifies that there are four and only four cases in which classes must be initialized immediately. When you encounter four bytecode instructions — New, getStatic, putStatic, or invokeStatic — you need to trigger initialization if the class has not already been initialized. The most common Java code scenario for generating these four instructions is: 1) use the new keyword to instantiate objects (2) read a static field of a class (the final modification, has put the results in the constant pool at compile-time except static fields) 3) set up a static field of a class (the final modification, has put the results in the constant pool at compile-time except static fields) 4) call a static method of a class
Class life cycle?
The life cycle of a class typically goes through five phases: load, connect, initialize, use, and unload
Class loading mechanism
We can talk about the parent delegate model for classLoaders.
Double check the DCL
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if(singleton == null) { singleton = new Singleton(); }}}returnsingleton; }}Copy the code
Synchronized blocks ensure that only one object is created. But by adding a layer of judgment on top of synchronized, you can prevent objects from entering synchronized blocks once they are created. This scheme not only reduces the granularity of locks and ensures thread safety, but also greatly improves performance.
It is important to note that volatile is used for multithreaded visibility, but it is used to prevent instruction reordering.
Extension:
Why volatile? What is volatile good for?
- First, visibility, which is unquestionable, and then perhaps the Java memory model.
- Prevent instruction reordering: Prevent instruction reordering on a New Singleton from causing another thread to acquire an uninitialized object. Instance = new Singleton(), which is not an atomic operation, actually does three things in the JVM. 1. Allocate memory for instance 2. Call the Singleton constructor to initialize member variable 3. The instance object is referred to the allocated memory space (the instance is not null after this step) but there is an optimization for instruction reordering in the JVM’s just-in-time compiler. That is to say, the order of step 2 and step 3 above is not guaranteed, and the final execution order may be 1-2-3 or 1-3-2. If it is the latter, instance is preempted by thread 2 before instance 3 is executed and instance 2 is already non-null (but not initialized), so thread 2 returns instance directly, uses it, and then reports an error.
- Volatie also uses memory barriers
Talk about the difference between synchronized and volatile
Synchroized is the guarantee of atomization, but volatile is not. Synchroized is the guarantee of heavyweight locks, and even the difference between them and locks.
How is thread safety generally implemented?
- Mutually exclusive synchronization. If the lock, synchroized
- Non-blocking synchronization. Such as cas.
- Out of sync. Like threadLocal, local variables.
Enumeration class
public enum Singleton{
INSTANCE;
}
Copy the code
The default enumerated instances are created thread-safe, so there is no need to worry about thread-safety. It is also a recommended pattern in Effective Java. Finally, by enumerating classes, he can automatically avoid serialization/deserialization attacks, as well as reflection attacks (enumerating classes cannot be generated by reflection).
conclusion
While the singleton pattern may seem simple, the Java basics of design are extensive, such as static modifiers, synchronized modifiers, volatile modifiers, enum, and so on. Each of these points can be turned into a test point for the interviewer, and the example is just a primer to see how much you know at the end of the test. Look at your breadth and depth.
Finally, this article was included in JGrowing, a comprehensive and excellent Java learning path co-built by the community. If you want to participate in the maintenance of open source projects, you can co-build it. The address on Github is github.com/javagrowing… A little star, please.
If you feel that this article is helpful to you, or want to get the subsequent chapters in advance, or you have any questions to provide 1V1 free VIP service, you can pay attention to my public account your attention and forwarding is the biggest support for me, O(∩_∩)O: