当前位置:网站首页>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 !
边栏推荐
- 2022 construction elevator driver (construction special type of work) examination questions and online simulation examination
- Go语言三个高效编程的技巧
- SaaS management system solution of smart Park: enabling the park to realize information and digital management
- 打败 二叉树!
- Harmony os. (2)
- 杰理之.睡眠以后定时唤醒系统继续跑不复位【篇】
- MySQL复合索引探究
- 杰理之TIMER0 用默认的 PA13 来检测脉宽【篇】
- unity 等高线创建方法
- 杰理之无缝循环播放【篇】
猜你喜欢

**Puzzling little problem in unity - light and sky box

OpenHarmony 1

HarmonyOS.2

Solution of channel management system for food and beverage industry: realize channel digital marketing layout
![根据前序&中序遍历生成二叉树[左子树|根|右子树的划分/生成/拼接问题]](/img/f7/8d026c0e4435fc8fd7a63616b4554d.png)
根据前序&中序遍历生成二叉树[左子树|根|右子树的划分/生成/拼接问题]

MIT-6.824-lab4A-2022(万字讲解-代码构建)

日常知识科普

Go语言三个高效编程的技巧
![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]
![Jerrys timer0 uses the default pa13 to detect the pulse width [chapter]](/img/4e/de0951c8be5ddd765b15b773c04fa7.png)
Jerrys timer0 uses the default pa13 to detect the pulse width [chapter]
随机推荐
How to manage tasks in the low code platform of the Internet of things?
Win10 system problems
简谈企业Power BI CI /CD 实施框架
Convolution kernel and characteristic graph visualization
ssh-keygen 配置无需每次输入密码
Telecommuting: camping at home office gadgets | community essay solicitation
常见的单例模式&简单工厂
杰理之无缝循环播放【篇】
AntD checkbox,限制选中数量
Defoaming
10_那些格調很高的個性簽名
Jericho turns on shouting in all modes to increase mic automatic mute [chapter]
【从零开始学zabbix】一丶Zabbix的介绍与部署Zabbix
融云通信“三板斧”,“砍”到了银行的心坎上
JS remove string spaces
杰理之.睡眠以后定时唤醒系统继续跑不复位【篇】
Ti Xing Shu'an joined the dragon lizard community to jointly create a network security ecosystem
2022 construction elevator driver (construction special type of work) examination questions and online simulation examination
Generate binary tree according to preorder & inorder traversal [partition / generation / splicing of left subtree | root | right subtree]
21set classic case