浅谈设计模式之单例模式

0 单例模式简介

单例模式属于创建型模式,它提供了一种创建对象的最佳方式。单例模式指的是单一的一个类 ,该类负责创建自己的对象,并且保证该对象唯一 。该类提供了一种访问其唯一对象的方法,外部需要调用该类的对象可以通过方法获取,不需要实例化类的对象。
关键点:

  • 单例类只能有一个实例
  • 单例类只能自己创建自己的唯一实例
  • 单例类需要给其他对象提供这一实例

1 实现方式

创建一个Singleton单例类,单例类有一个私有的构造方法和私有的唯一静态实例。Singleton对象提供了一个公有的静态方法,供外界调用其唯一的静态实例。SingletonDemo类使用Singleton类来获取Singleton对象。

此处主要用以下三种创建方式举例说明。

1.1 懒汉式,线程安全

  • 优点:第一次调用才初始化,避免内存资源浪费
  • 缺点:必须要加synchronize锁才能保证单例,但是加锁会影响效率

创建单例类:

java 复制代码
public class Singleton {
  //实现方式一:懒汉式 线程不安全
    private static Singleton instance;
    private Singleton(){}
    public static synchronized Singleton getInstance(){
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    public void show() {
        System.out.println("singleton");
    }
}

调用单例类获取唯一对象实例:

java 复制代码
public class SingletonDemo {
    public static void main(String[] args) {
        //获取唯一的可用对象
        Singleton obj = Singleton.getInstance();
        //调用instance的方法
        obj.show();
    }
}

1.2 饿汉式,线程安全

  • 优点:没有加锁,执行效率更高
  • 缺点:类加载时就会实例化,浪费内存
    该方式基于 classloader 机制避免了多线程的同步问题。
    创建单例类:
java 复制代码
public class Singleton {
  //实现方式二:饿汉式 线程安全
    private static Singleton instance = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
    public void show() {
        System.out.println("singleton");
    }
}

1.3 双检锁/双重校验锁

这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

java 复制代码
public class Singleton {
  //实现方式三:双重校验锁 线程安全
    private volatile static Singleton instance;
    private Singleton(){}
    public static Singleton getInstance(){
        if (instance == null) {
            synchronized (Singleton.class) {
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
    public void show() {
        System.out.println("singleton");
    }
}

2 小结

  • 单例类仅有一个实例,并且对外提供获取实例的方法
  • 主要解决一个全局使用的类频繁的创建与销毁
  • 构造方法为私有
相关推荐
十五年专注C++开发13 分钟前
QT 中的元对象系统(五):QMetaObject::invokeMethod的使用和实现原理
开发语言·数据结构·c++·qt·设计模式
倒霉蛋小马1 小时前
【Java集合】LinkedList源码深度分析
java·开发语言
风象南1 小时前
SpringBoot中6种API版本控制策略
java·spring boot·后端
小周不摆烂3 小时前
Java Web从入门到精通:全面探索与实战(一)
java
cherryc_3 小时前
JavaSE基础——第六章 类与对象(二)
java·开发语言
快来卷java3 小时前
JVM虚拟机篇(三):JVM运行时数据区与方法区详解
java·jvm·mysql
whltaoin4 小时前
Java实现N皇后问题的双路径探索:递归回溯与迭代回溯算法详解
java·算法
nlog3n6 小时前
Java策略模式详解
java·bash·策略模式
Amd7947 小时前
FastAPI依赖注入实践:工厂模式与实例复用的优化策略
单例模式·性能优化·fastapi·工厂模式·依赖注入·多租户系统·实例复用
Mryan20059 小时前
解决GraalVM Native Maven Plugin错误:JAVA_HOME未指向GraalVM Distribution
java·开发语言·spring boot·maven