当前位置:网站首页>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 !
边栏推荐
- **Puzzling little problem in unity - light and sky box
- leetcode:1504. 统计全 1 子矩形的个数
- NPM package [details] (including NPM package development, release, installation, update, search, uninstall, view, version number update rules, package.json details, etc.)
- leetcode:1504. Count the number of all 1 sub rectangles
- Rasa 3.x 学习系列-非常荣幸成为 Rasa contributors 源码贡献者,和全世界的Rasa源码贡献者共建共享Rasa社区!
- In the era of knowledge economy, it will teach you to do well in knowledge management
- 杰理之增加一个输入捕捉通道【篇】
- 数据库注意事项
- One click to generate University, major and even admission probability. Is it so magical for AI to fill in volunteer cards?
- 融云通信“三板斧”,“砍”到了银行的心坎上
猜你喜欢

win10系统问题

IDEA连接mysql自定义生成实体类代码

智慧园区SaaS管理系统解决方案:赋能园区实现信息化、数字化管理

pgsql查询分组中某个字段最大或者最小的一条数据

Win10 system problems

MySQL日志管理、备份与恢复

Kunpeng arm server compilation and installation paddlepaddle

Antd checkbox, limit the selected quantity

SAP Marketing Cloud 功能概述(四)

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!
随机推荐
Research and development practice of Kwai real-time data warehouse support system
如何避免下重复订单
如何解决 Iterative 半监督训练 在 ASR 训练中难以落地的问题丨RTC Dev Meetup
Operation of simulated examination platform of examination question bank for B certificate of Jiangxi provincial safety officer in 2022
Jerry added an input capture channel [chapter]
远程办公之:在家露营办公小工具| 社区征文
Return to new list
Télétravail: Camping à la maison gadgets de bureau | rédaction communautaire
HarmonyOS-3
Method of inputting dots under letters in markdown/latex
Second, the examinee must see | consolidate the preferred question bank to help the examinee make the final dash
How to solve the problem that iterative semi supervised training is difficult to implement in ASR training? RTC dev Meetup
Development of B2B transaction collaborative management platform for kitchen and bathroom electrical appliance industry and optimization of enterprise inventory structure
根据前序&中序遍历生成二叉树[左子树|根|右子树的划分/生成/拼接问题]
Win10 system problems
2022 coal mine gas drainage operation certificate examination questions and simulation examination
ssh-keygen 配置无需每次输入密码
MES在流程和离散制造企业的15个差别(下)
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!
Antd checkbox, limit the selected quantity