Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the details of the singleton pattern?

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "what are the details of the singleton pattern". In the daily operation, I believe many people have doubts about the details of the singleton pattern. The editor consulted all kinds of data and sorted out simple and easy-to-use methods of operation. I hope it will be helpful for you to answer the doubts about "what are the details of the singleton pattern?" Next, please follow the editor to study!

Since last year, it has become more and more difficult for Java programmers to change jobs. They don't understand multithreading, JVM,mysql, and some distributed components.

I often hear the students around me say that the interview topic around me is very simple, and I can do it myself, but when it comes to myself, can you speak thoroughly on a point of knowledge, and can you diverge thinking and lead to more answers?

This handwritten written test of a singleton mode should have been encountered by many programmers. They may be surprised and feel lucky when they first see the question, but can you really do it 100% well?

Please write a single example by hand, which requires thread safety.

First, give a definition to the singleton: in the current process, there is one and only one instance of the class created through the singleton pattern.

A single case has the following characteristics:

In Java applications, the singleton pattern ensures that only one instance of the object exists in a JVM.

The constructor must be private and the external class cannot create the instance by calling the constructor method

Without an exposed set method, an external class cannot call the set method to create the instance

Provide a public get method to get a unique instance of this

So what are the benefits of the singleton model?

Some classes are created frequently, which is a lot of overhead for some large objects

Omit the new operator, reduce the use frequency of system memory, and reduce the pressure of GC

Some classes in the system, such as controller in spring, control the processing flow, and if the class can create multiple, the system is completely messed up.

All right, the definition of the singleton pattern is clear, and the benefits are understood. Let's take a look at a hungry Chinese style first.

Public class Singleton {private static Singleton instance = new Singleton (); / * Private constructors to prevent instantiation of * / private Singleton () {} / * static get methods * / public static Singleton getInstance () {return instance;}}

If this answer is provided during the interview, then PC recommends that you go home and study hard for two months before you come out to look for a job. You must say that this is too low, it seems that the thread is not safe, and the method should be locked through synchronized. At the same time, check it before creation, and write it as follows:

Public class Singleton {private static Singleton instance = null; / * private constructors to prevent instantiation of * / private Singleton () {} / * static get methods * / public static synchronized Singleton getInstance () {if (instance = = null) {instance = new Singleton ();} return instance;}}

This is a typical time-for-space writing method, regardless of three, seven or twenty-one, lock it up every time you create an instance, and then make a judgment, which seriously reduces the processing speed of the system.

Is there a better way to deal with it?

Yes, make a judgment twice through the double check lock. The code is as follows:

Public class Singleton {private static Singleton instance = null Private Singleton () {} public static Singleton getInstance () {/ / first check whether the instance exists. If not, enter the following synchronization block if (instance = = null) {/ / synchronization block. Thread-safe create instance synchronized (Singleton.class) {/ / check whether the instance exists again. Create the instance if (instance = = null) {instance = new Singleton () if it doesn't exist. } return instance;}}

The synchronized keyword is added internally, that is, it does not need to be locked when it is called, but only when the instance is null and the object is created, so the performance is improved to a certain extent.

But is there no problem?

Consider the following: the object creation and assignment operations in the Java instruction are done separately, that is, instance = new Singleton (); the statement is executed in two steps.

However, JVM does not guarantee the order of these two operations, which means that it is possible that JVM will allocate space to the new Singleton instance, then assign values directly to instance members, and then initialize the Singleton instance.

This may go wrong, let's take An and B threads as an example:

Thread An and thread B enter the first if judgment at the same time

A first enters the synchronized block. Since instance is null, it executes instance = new Singleton ()

Due to the optimization mechanism within JVM, JVM first draws some blank memory allocated to the Singleton instance and assigns values to the instance members (note that JVM does not start initializing the instance at this time), and then A leaves the synchronized block.

Image-20201212010622553

B enters the synchronized block, and since instance is not a null at this time, it immediately leaves the synchronized block and returns the result to the program that called the method.

At this point, the B thread intends to use the Singleton instance, only to find that it is not initialized, and an error occurs.

Add volatile to modify Singleton, and optimize it again:

Public class Singleton {private volatile static Singleton instance = null Private Singleton () {} public static Singleton getInstance () {/ / first check whether the instance exists. If not, enter the following synchronization block if (instance = = null) {/ / synchronization block. Thread-safe create instance synchronized (Singleton.class) {/ / check whether the instance exists again. Create the instance if (instance = = null) {instance = new Singleton () if it doesn't exist. } return instance;}}

* * variables modified by volatile will not be cached locally by the thread, and all thread reads and writes to the object will be synchronized to the main memory at the first time, thus ensuring the accuracy of the object among multiple threads * *

The role of volatile

Prevent instruction reordering because instance = new Singleton () is not an atomic operation

Make sure the memory is visible

This is a perfect way to write it, and it can safely create a unique instance without having much impact on performance.

But because the volatile keyword may block some of the necessary code optimizations in the virtual machine, it is not very efficient, is there a better way to write it?

Through static inner classes

Public class Singleton {/ * private constructor to prevent instantiation * / private Singleton () {} / * an inner class is used here to maintain singletons * / private static class SingletonFactory {private static Singleton instance = new Singleton ();} / * get instance * / public static Singleton getInstance () {return SingletonFactory.instance } / * if the object is used for serialization, the object can be guaranteed to be consistent before and after serialization * / public Object readResolve () {return getInstance ();}}

Using inner classes to maintain singleton implementations, JVM's internal mechanism ensures that when a class is loaded, the loading process of that class is thread mutually exclusive.

In this way, when we call getInstance for the first time, JVM can ensure that the instance is created only once and that the memory assigned to instance is initialized, so we don't have to worry about the above problems.

At the same time, this method only uses the mutex mechanism when it is called for the first time, which solves the problem of low performance. So let's summarize a perfect singleton model for the time being.

Is there a more perfect way to write it by enumerating:

Public enum Singleton {/ * defines an enumerated element, which represents an instance of Singleton. * / Instance;}

It is more concise to use enumerations to implement single instance control, and JVM provides a fundamental guarantee to absolutely prevent multiple instantiations, which is a more concise, efficient and secure way to implement singletons.

At this point, the study of "what are the details of the singleton pattern" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report