当前位置:网站首页>Common singleton mode & simple factory
Common singleton mode & simple factory
2022-06-24 14:16:00 【Yilin YL】
Catalog
1. Simple method of one-way judgment
3. Instantiate this class through a static inner class
1. The concept of factory pattern :
2. Usage scenario of factory mode :
Preface :
Why should we learn design patterns : Design patterns (disign pattern) Represents best practice , It is the experience of many excellent software developers , It is a solution to a specific problem . It is not a grammatical rule , And don't stick to a particular language . Proper use of design patterns can make code more reusable 、 Maintainability 、 Extensibility 、 Robustness and security , These are very important non functional requirements of the system .
First, let's briefly analyze several common singleton patterns .
The singleton pattern :
1. The concept of singleton pattern : As the name suggests, only one instance will be used in memory .
2. The difference between the two singleton modes :
① The main difference between the two is Objects are created at different times : Hungry man mode creates objects when classes are loaded , Lazy mode is created when it is used ( That is, the instance object method is created when it is called ).
② The second is the thread safety of both : Hungry man mode is a single thread mode , So there will be no thread safety issues . This is the problem with the lazy man model .
3. Advantages and disadvantages of singleton mode :
advantage :
- There is only one object in memory , Save memory space ;
- Avoid frequent creation of destroyed objects , Can improve performance ;
- Avoid multiple use of shared resources , Simplify access ;
- Provide a global access point for the whole system .
shortcoming :
- Not for objects that change frequently ;
- Abuse of single case will bring some negative problems , For example, in order to save resources, the database connection pool object is designed as a single instance class , May cause too many programs sharing connection pool objects to overflow connection pool ;
The singleton mode is divided into the following two types :
One , Starving model
Let's make it simple : Hungry man mode is to instantiate a singleton while defining it , It can be used directly . In other words, in the hungry man mode , stay SingletonDemo01 An instance of this class already exists in JVM It's in . In this way, it is easier to understand .
The code is as follows :
package com.ljq.text;
/**
* The singleton pattern - Starving model
* @author Yilin
*
*/
public class SingletonDemo01 {
// 1. You need to have a private constructor , Prevent this class from passing new To create an instance
private SingletonDemo01() {
}
// 2. Hunger mode , First, generate an instance
private static final SingletonDemo01 instance = new SingletonDemo01();
// 3. Static methods , Used to get the generated instance
public static SingletonDemo01 getInstance() {
return instance;
}
public String hello(String name) {
return "hello " + name;
}
/**
* Test whether multithreading is a safe method
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(SingletonDemo01.getInstance().hashCode());
}).start();
}
SingletonDemo01 s = SingletonDemo01.getInstance();
String hello_world = s.hello("world");
System.out.println(hello_world);
}
}
Realization principle :
1️⃣ Privatize the constructor , To prevent this class from being new Form examples of
2️⃣ Create a static variable , This constant is new Out of this class , It is static because static attributes or methods belong to classes , It can better ensure the uniqueness of the singleton pattern .
3️⃣ Create a static method to return constants , That is, the generated instance
Here we also create a common method by the way hello Pass in a string Parameter is used to return hello Concatenate the string of this parameter to facilitate our test .
test :
1️⃣ This call 100 Threads call static methods through class names and then use hashcode Method to print out the final result .
2️⃣ Then the test calls the static method through the class name getInstance Get the instance class of this class and call hello How to print .
The console results are as follows :

We'll find out , Use hashcode Method prints the same results .
Two , The sluggard model
The lazy man model has the possibility of wasting resources .
There are four main ways of starving Han mode :
1. Simple method of one-way judgment
This is actually a relatively simple lazy man mode , So the latter method is also changed on this .
The code is as follows :
package com.ljq.text;
import java.net.Socket;
/**
* The singleton pattern - Slacker type ( There are thread safety issues )
*
* @author Yilin
*
*/
public class SingletonDemo02 {
private SingletonDemo02() {
// The running time of the simulation constructor
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static SingletonDemo02 singletonDemo02 = null;
public static synchronized SingletonDemo02 getInstance() {
if (singletonDemo02 == null) {
singletonDemo02 = new SingletonDemo02();
}
return singletonDemo02;
}
public String hello(String name) {
return "hello " + name;
}
/*
* Test whether the multi-threaded singleton mode is safe
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(SingletonDemo02.getInstance().hashCode());
}).start();
}
}
}
Realization principle :
1️⃣ Privatize the constructor , The running time of the construction method is simulated in the construction method .
2️⃣ Define a static variable and initialize it to null
3️⃣ Define the method to obtain the instance class and apply the synchronization lock , Add judgment to the method body , If the static constant is null Value is assigned to it
We tested and found that :
Through the console results, the results of the 100 threads we traverse are consistent , But it's not like this , This method still has security problems , It just doesn't happen every time .
2. Double check lock method
Compare our one-way judgment method above , Although the lazy mode can realize the singleton under multithreading , But rough will getInstance() lock , Such a price is actually very high , Why? ?
because , Only when the first call getInstance() You need to create objects synchronously , Call again after creation getInstance() Yes, it simply returns the member variable , There is no need to synchronize , So there is no need to lock the whole method .
Because synchronizing a method reduces 100 Times or more performance , The overhead of acquiring or releasing locks per call can be avoided : Once the initialization is complete , It is unnecessary to obtain the release lock .
So there is a double check lock mode :
Double lock mode refers to further optimization based on lazy mode , Add... To the definition of static objects volatile lock To ensure the uniqueness of objects during initialization , When getting an object, use synchronized (Singleton.class) Lock the singleton class to ensure the uniqueness of the operation .
The code is as follows :
package com.ljq.text;
/**
* The singleton pattern - Slacker type ( Double judgmental , Thread safety , But the performance is lower )
*
* @author Yilin
*
*/
public class SingletonDemo03 {
private SingletonDemo03() {
// The running time of the simulation constructor
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static SingletonDemo03 singletonDemo03 = null;
public static SingletonDemo03 getInstance() {
// The system reduces the synchronization block to improve performance , Is that OK ?
if (singletonDemo03 == null) {
/// ....
synchronized (SingletonDemo03.class) {
if (singletonDemo03 == null) {
singletonDemo03 = new SingletonDemo03();
}
}
}
return singletonDemo03;
}
public String hello(String name) {
return "hello " + name;
}
/*
* Test whether the multi-threaded singleton mode is safe
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(SingletonDemo03.getInstance().hashCode());
}).start();
}
}
}
In fact, the whole process is also very clear and simple :
① Check if the variable is initialized ( Don't get the lock first ), If it has already been initialized, return this variable immediately
② Gets the lock
③ The second time, check whether the variable has been initialized : If another thread has ever acquired a lock , Then the variable has been initialized , Returns the initialized variable
④ otherwise , Initialize and return variables
So! , The reason for the second verification is to prevent re creation , If there is a situation , When singletonDemo03 When the thread has not been created T1 call getInstance(), Because of the first judgment singletonDemo03 ==null, The thread T1 Ready to continue , But because the resources are used by threads T2 Take over , here T2 call getInstance(), similarly , because singletonDemo03 There is no instantiation ,T2 You can also pass the first if, And then move on , Synchronization code block , the second if Also through , Then the thread T2 Created an instance singletonDemo03 . The thread T2 To complete the task , The resource returns to the thread T1,T1 This also enters the synchronization code block , Without this, the second if, that ,T1 It will also create a singletonDemo03 example , that , Multiple instances will be created , But add the second if, You can completely avoid the problem of multiple instances created by this multithreading .
3. Instantiate this class through a static inner class
The code is as follows :
package com.ljq.text;
/**
* The singleton pattern - Lazy loading ( Thread safety )
*
* @author Yilin
*
*/
public class SingletonDemo04 {
// Prevent external instantiation
private SingletonDemo04() {
// The simulation constructor takes time to run
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static {
}
// Use a static inner class to use a SingletonDemo04 object
private static class SingletonDemoHolder {
private final static SingletonDemo04 instance = new SingletonDemo04();
}
public static SingletonDemo04 getInstance() {
return SingletonDemoHolder.instance;
}
public String hello(String name) {
return "hello " + name;
}
/*
* Test whether the multi-threaded singleton mode is safe
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(SingletonDemo04.getInstance().hashCode());
}).start();
}
System.out.println(SingletonDemo04.getInstance());
}
}
test result :
4. Enumeration method :
Enum The full name is enumeration, Chinese is commonly known as Enumeration class .
Speaking of enumerating classes , Have studied or understood C/C++ All of us should know something about him .
But in Java In the category of language , Is in JDK5 Was introduced in the version of .enum Is the keyword used to declare
The code is as follows :
package com.ljq.text;
/**
* The singleton pattern - Enumeration type
* @author Yilin
*
*/
public enum SingletonDemo05 {
INSTANCE;
public String hello(String name) {
return "hello " + name;
}
/*
* Test whether the multi-threaded singleton mode is safe
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(SingletonDemo05.INSTANCE.hashCode());
}).start();
}
}
}
Factory mode
1. The concept of factory pattern :
Methods or classes used to generate objects , Call it a factory . The singleton pattern mentioned above can also be regarded as a special factory .
2. Usage scenario of factory mode :
Why working mode is needed , The original use new The way is also very simple , And easy to understand ?
The reason for using the factory is that we can use the factory mode , To centrally control the creation process of objects , This can bring more flexibility to the design .
such as :spring Of IOC A container is a classic implementation of the factory pattern .
3. Factory method :
Used to produce the specified series of objects . Take the duck as an example , Ducks have real ducks , Rubber duck , Electronic toy duck, etc . How to easily create a variety of ducks , And control the creation process , To facilitate future maintenance and expansion ?
The diagram is as follows :

We now have a duck shop :
package com.ljq.factory;
/**
* Duck's abstract class
*
* @author Yilin
*
*/
public abstract class Duck {
abstract public void quack();
}
There are four kinds of ducks in our store :
package com.ljq.factory;
/**
*
* @author Yilin
*
*/
public class PinkDuck extends Duck {
@Override
public void quack() {
System.out.println(" I am a pink duck ");
}
}
package com.ljq.factory;
/**
*
* @author Yilin
*
*/
public class WildDuck extends Duck {
@Override
public void quack() {
System.out.println(" I am a real duck ");
}
}
package com.ljq.factory;
/**
*
* @author Yilin
*
*/
public class RubberDuck extends Duck {
@Override
public void quack() {
System.out.println(" I'm a rubber duck ,");
}
}
package com.ljq.factory;
/**
*
* @author Yilin
*
*/
public class DonaldDuck extends Duck {
@Override
public void quack() {
System.out.println(" I'm Donald Duck ");
}
}
Then we need a waiter to communicate with the customer which one to buy ?:
package com.ljq.factory;
/**
*
* @author Yilin
*
*/
public class DuckFactory {
private DuckFactory() {
}
private static DuckFactory duckFactory = new DuckFactory();
public static final int WILD_DUCK = 1;
public static final int RUBBER_DUCK = 2;
public static final int DONALD_DUCK = 3;
public static final int Pink_DUCK = 4;
public static Duck getInstance(int duckType) {
switch (duckType) {
case WILD_DUCK:
return new WildDuck();
case RUBBER_DUCK:
return new RubberDuck();
case DONALD_DUCK:
return new DonaldDuck();
case Pink_DUCK:
return new PinkDuck();
default:
return null;
}
}
}
Finally the guests came , The guests were very satisfied with our service , Bought all the varieties of our store at one go :
package com.ljq.factory;
/**
*
* @author Yilin
*
*/
public class Main {
public static void main(String[] args) {
Duck donaldDuck = DuckFactory.getInstance(DuckFactory.DONALD_DUCK);
donaldDuck.quack();
Duck wildDuck = DuckFactory.getInstance(DuckFactory.WILD_DUCK);
wildDuck.quack();
Duck pinkDuck = DuckFactory.getInstance(DuckFactory.Pink_DUCK);
pinkDuck.quack();
Duck rubberDuck = DuckFactory.getInstance(DuckFactory.RUBBER_DUCK);
rubberDuck.quack();
}
}
The results printed out by the console :

Above our simple factory model . Is it easier to understand in this way .
In the next issue, I will bring you Abstract factories and more knowledge , I hope my understanding will help you . See you next time !
边栏推荐
- Jerry's test mic energy automatic recording automatic playback reference [article]
- HarmonyOS-3
- English writing of Mathematics -- Basic Chinese and English vocabulary (common vocabulary of geometry and trigonometry)
- conda和pip命令
- leetcode:1504. Count the number of all 1 sub rectangles
- win10系统问题
- The real project managers are all closed-loop masters!
- 10 Ces autographes très stylisés.
- AutoRF:从单视角观察中学习3D物体辐射场(CVPR 2022)
- 【从零开始学zabbix】一丶Zabbix的介绍与部署Zabbix
猜你喜欢
![Jerry's serial port receiving IO needs to set the digital function [chapter]](/img/04/48e7da42101a53827463d479952f67.png)
Jerry's serial port receiving IO needs to set the digital function [chapter]

Research and development practice of Kwai real-time data warehouse support system

c语言---18 函数(自定义函数)
![[R language data science] (XIV): random variables and basic statistics](/img/87/3606041a588ecc615eb8013cdf9fb1.png)
[R language data science] (XIV): random variables and basic statistics

Unity 热力图建立方法

Télétravail: Camping à la maison gadgets de bureau | rédaction communautaire

Rasa 3. X learning series - it is a great honor to be a source code contributor of Rasa contributors, and to build and share the rasa community with rasa source code contributors all over the world!

Rongyun communication has "hacked" into the heart of the bank

AutoRF:从单视角观察中学习3D物体辐射场(CVPR 2022)

数字臧品系统开发 NFT数字臧品系统异常处理源码分享
随机推荐
Google waymo proposed r4d: remote distance estimation using reference target
Development of B2B transaction collaborative management platform for kitchen and bathroom electrical appliance industry and optimization of enterprise inventory structure
【LeetCode】10、正则表达式匹配
How to manage tasks in the low code platform of the Internet of things?
Maximum path sum in binary tree [handle any subtree, then handle the whole tree]
Operation of simulated examination platform of examination question bank for B certificate of Jiangxi provincial safety officer in 2022
leetcode:1504. 统计全 1 子矩形的个数
杰理之在所有模式下打开喊话增加 mic 自动 mute【篇】
Télétravail: Camping à la maison gadgets de bureau | rédaction communautaire
v-for 中 key的作用和原理
Record various sets of and or of mongotemplate once
Unit contour creation method
Jerry added an input capture channel [chapter]
在线文本实体抽取能力,助力应用解析海量文本数据
Second, the examinee must see | consolidate the preferred question bank to help the examinee make the final dash
MIT-6.824-lab4A-2022(万字讲解-代码构建)
Dragon lizard developer said: first time you got an electric shock, so you are such a dragon lizard community| Issue 8
杰理之可能出现有些芯片音乐播放速度快【篇】
根据前序&中序遍历生成二叉树[左子树|根|右子树的划分/生成/拼接问题]
conda和pip命令