当前位置:网站首页>单例模式
单例模式
2022-07-26 15:14:00 【老蛙@】
设计模式的分类
创建型模式
单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式
结构型模式
适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式
行为型模式
模板方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式
单例模式
单例模式介绍
所谓单例模式,就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法;例如Hibernate的SessionFactory,它充当数据源的代理,并负责创建Session对象,SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory对象
饿汉式(静态常量)
/*** * @author shaofan * @Description 单例饿汉式,静态变量 */
public class Hungry1 {
/** * 私有化构造器,方式外部创建对象 */
private Hungry1(){
}
/** * 使用静态常量来创建对象,依靠类加载机制,静态变量只会在类初始化的时候加载一次,所以创建出来的对象是单例的 */
private final static Hungry1 INSTANCE = new Hungry1();
/** * 获取实例 * @return */
public Hungry1 getInstance(){
return INSTANCE;
}
}
优缺点
- 优点:写法简单,就是通过类加载机制在类装载的时候完成实例化,避免了线程同步问题
- 缺点:在类装在的时候就完成实例化,没有达到懒加载的效果,如果从始至终从未使用过这个实例,则会造成内存的浪费
- 这种方式基于classloader机制避免了多线程的同步问题,不过,instance在类装载时就是梨花,在单例模式中大多数都是调用getInstance方法,但是导致类加载的原因有很多种,因此不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候并不需要用到instance却初始化instance就没有达到懒加载的效果
- 这种单例模式可用,可能造成内存浪费(如果保证一定会用它就可以使用)
饿汉式(静态代码块)
/*** * @author shaofan * @Description 饿汉式,静态代码块 */
public class Hungry2 {
private static Hungry2 instance;
/** * 私有化构造器,防止外部new对象 */
private Hungry2(){
}
//在静态代码块来初始化实例
static {
instance =new Hungry2();
}
/** * 获取实例 * @return */
public static Hungry2 getINSTANCE() {
return instance;
}
}
优缺点
这种方式和静态变量的方式是一样的,都是利用类加载机制来完成实例的初始化
懒汉式(线程不安全)
/*** * @author shaofan * @Description 懒汉式,线程不安全 */
public class Lazy1 {
private static Lazy1 instance;
private Lazy1(){
}
/** * 获取instance时先判断是否为空,为空则创建,不为空则返回;但是在多线程环境下,可能多个线程同时检测为空,导致重复创建 * @return */
public static Lazy1 getInstance(){
if(instance==null){
instance = new Lazy1();
}
return instance;
}
}
优缺点
- 起到了懒加载的效果,但是只能在单线程下使用
- 如果在多线程下,一个线程进入了if判断语句块,还没有来的及往下执行,另一个线程也通过了这个判断语句,这是个时候就会产生多个实例
- 实际开发中,不推荐使用这样的方式
懒汉式(同步方法)
/*** * @author shaofan * @Description 懒汉式,同步方法 */
public class Lazy2 {
private static Lazy2 instance;
private Lazy2(){
}
/** * 使用synchronized关键字同步getInstance方法,保证同一时刻只有一个线程进入这个方法,就不会创建多个实例 * @return */
public static synchronized Lazy2 getInstance() {
if(instance==null){
instance = new Lazy2();
}
return instance;
}
}
优缺点
- 优点:解决了线程不安全问题
- 缺点:效率太低了,每个线程在想获得类的实例的时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化就够了,后面想获得实例直接return即可;直接在方法层面加上synchronized关键字会使每次调用都要加锁,效率低
- 在实际开发中,不推荐使用
双重检查
/*** * @author shaofan * @Description 懒汉式,双重检查 */
public class Lazy3 {
private static Lazy3 instance;
private Lazy3(){
}
/** * 通过类锁来同步代码块,多个线程先对instance进行空值判断,进行第一轮检查,第一次创建时会有少量线程进入,只对第一次创建时的线程加锁,进行第二层检查 * @return */
public Lazy3 getInstance(){
if(instance==null){
synchronized (Lazy3.class){
if(instance==null){
instance = new Lazy3();
}
}
}
return instance;
}
}
优缺点
- Double-Check概念是多线程开发中常使用到的,如代码中所示,进行了两次空值检查,第二次才会加锁,这样在保证线程安全的情况下提高了性能
- 线程安全、延迟加载、效率较高
- 在实际开发中,推荐使用
静态内部类
/*** * @author shaofan * @Description 静态内部类方式 */
public class StaticInner {
private StaticInner(){
}
/*** * 静态内部类不会在外部类加载的时候加载,而是具有自己的启动加载机制,当第一次调用到这个类的时候进行加载,也会有懒加载的效果,同时由于类的单次加载的特性, * 实例也是单例的 */
private static class Instance{
private static final StaticInner INSTANCE = new StaticInner();
}
public StaticInner getInstance(){
return Instance.INSTANCE;
}
}
优缺点
- 这种方式采用了类装载机制来保证初始化实例只有一个线程
- 静态内部类方式在外部类加载的时候并不会立即实例化,而是在需要实例化的时候,调用getInstance方法,才会装载内部类,从而完成实例化
- 类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮我们保证了线程安全,不会有多个线程将类进行多次的初始化
- 优点:线程安全,利用静态内部类实现了延迟加载,效率高
- 推荐使用
枚举
/*** * @author shaofan * @Description 枚举方式 */
public enum Singleton {
INSTANCE;
}
优缺点
- 借助jdk1.5添加的枚举来实现单例模式,不仅能避免线程问题,而且还能防止反序列化重新创建新的对象
- 这种方式还是Effective Java作者提倡的方式
- 推荐使用
单例模式源码分析
在JDK中,java.lang.Runtime就使用到了单例模式
这里使用的是饿汉式的单例模式
总结
- 单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些要频繁拆功能键销毁的对象,使用单例模式可以提高系统性能
- 当需要实例化一个单例类的时候,必须使用相应的获取实例的方法,而不是new
- 单例模式使用的场景:需要频繁创建和销毁的对象、创建对象时耗时过多或者耗费资源过多(重量级对象),但又常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)
边栏推荐
- MYSQL 命令大全
- R语言使用lm函数构建多元回归模型(Multiple Linear Regression)、并根据模型系数写出回归方程、使用fitted函数计算出模型的拟合的y值(响应值)向量
- [leave some code] Apply transformer to target detection, and understand the model operation process of the model through debug
- Jintuo shares listed on the Shanghai Stock Exchange: the market value of 2.6 billion Zhang Dong family business has a strong color
- [leetcode daily question] - 268. Missing numbers
- [basic] the difference between dynamic link library and static link library
- Within a week, I developed my own knowledge sharing platform
- USB转串口参数配置功能
- [5 minutes paper] Pointer network
- Pytorch--- advanced chapter (function usage skills / precautions)
猜你喜欢

Practical task scheduling platform (scheduled task)

QT is the most basic layout, creating a window interface

Qt最基本的布局,创建window界面

81.(cesium之家)cesium修改灰色背景(默认蓝色)

Devsecops, speed and security

持续集成(一)基本概念简要介绍

In the changing era of equipment manufacturing industry, how can SCM supply chain management system enable equipment manufacturing enterprises to transform and upgrade

How do college students apply for utility model patents?

【五分钟Paper】基于参数化动作空间的强化学习

工具技能学习(二):前置技能-shell
随机推荐
软测(七)性能测试(1)简要介绍
In the changing era of equipment manufacturing industry, how can SCM supply chain management system enable equipment manufacturing enterprises to transform and upgrade
Pytorch installation CUDA corresponding
蓝牙BLE4.0-HM-10设备配对指南
Data preprocessing of data mining
Operation method of abbkine elikine human alpha fetoprotein (AFP) ELISA quantitative Kit
MYSQL 命令大全
R语言ggplot2可视化:使用ggplot2可视化散点图、使用ggpubr包的theme_pubclean函数设置可视化图像不包含坐标轴线的主题(theme without axis lines)
Prometheus adds redis and MySQL node monitoring
Sqldeveloper tools quick start
anaconda No module named ‘cv2‘
Strengthen the defense line of ecological security, and carry out emergency drills for environmental emergencies in Guangzhou
Practical task scheduling platform (scheduled task)
R语言ggplot2可视化:使用ggpubr包的ggdotplot函数可视化点阵图(dot plot)、设置add参数添加均值和标准差竖线、设置error.plot参数实际显示箱体
cs224w(图机器学习)2021冬季课程学习笔记5
What is the transport layer protocol tcp/udp???
R language ggplot2 visualization: use ggplot2 to visualize the scatter diagram, and use the theme of ggpubr package_ The pubclean function sets the theme without axis lines in the visual image
广州地铁十三号线二期全线土建已完成53%,预计明年开通
TI C6000 TMS320C6678 DSP+ Zynq-7045的ZYNQ PS + PL异构多核案例开发手册(1)
桌面应用布局图