浅谈设计模式之单例模式

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 小结

  • 单例类仅有一个实例,并且对外提供获取实例的方法
  • 主要解决一个全局使用的类频繁的创建与销毁
  • 构造方法为私有
相关推荐
zaim139 分钟前
计算机的错误计算(一百一十四)
java·c++·python·rust·go·c·多项式
hong_zc2 小时前
算法【Java】—— 二叉树的深搜
java·算法
进击的女IT3 小时前
SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS
java·spring boot·后端
Miqiuha3 小时前
lock_guard和unique_lock学习总结
java·数据库·学习
一 乐4 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
数云界4 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
阑梦清川4 小时前
Java继承、final/protected说明、super/this辨析
java·开发语言
快乐就好ya6 小时前
Java多线程
java·开发语言
IT学长编程6 小时前
计算机毕业设计 二手图书交易系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·二手图书交易系统
CS_GaoMing6 小时前
Centos7 JDK 多版本管理与 Maven 构建问题和注意!
java·开发语言·maven·centos7·java多版本