首页 > 其他分享 >单例模式五种实现方式以及在JDK中的体现

单例模式五种实现方式以及在JDK中的体现

时间:2024-02-21 10:47:45浏览次数:20  
标签:JDK 私有 private INSTANCE 五种 static 单例 public

单例模式五种实现方式以及在JDK中的体现

一、五种实现方式

1、饿汉式

  • 构造私有
  • 提供一个静态私有的成员常量,类型就是单例类型,值是用私有构造创造出来的唯一实例
  • 提供公共的静态方法获取上述的静态成员常量
public class Singleton1 implements Serializable {
    //(1)构造私有
    private Singleton1(){
        //添加if判断防止单例模式被破坏
        if(INSTANCE != null) {
            throw new RuntimeException("单例构造器禁止反射调用");
        }
        System.out.println("private Singleton1()");
    }
    //(2)提供一个静态私有的成员常量,类型就是单例类型,值是用私有构造创造出来的唯一实例
    private static final Singleton1 INSTANCE = new Singleton1();
    //(3)提供公共的静态方法获取上述的静态成员常量
    public static Singleton1 getInstance() {
        return INSTANCE;
    }
}

注意:对应所有的单例模式实现方式,如果实现Serializable接口,可能会被反射,反序列化等操作破坏单例,

2、枚举饿汉式

  • 枚举类,只定义一个变量
  • 构造私有
  • 提供公共的静态方法获取枚举常量
public enum Singleton2 {
    //(1)枚举类,只定义一个变量
    INSTANCE;
    //(2)构造私有
    private Singleton2(){
        System.out.println("private Singleton3()");
    }
    //(3)获取枚举常量
    private static Singleton2 getInstance(){
        return INSTANCE;
    }

}

3、懒汉式

  • 构造私有
  • 提供一个静态私有的成员常量,类型就是单例类型,值为空
  • 当调用该方法时才new
  • 提供公共的静态方法获取上述的静态成员常量
public class Singleton3 {
    //(2)声明静态变量为空
    private static Singleton3 INSTANCE = null;
    //(1)构造私有
    private Singleton3(){
        System.out.println("private Singleton1()");
    }
    //(3)提供公共的静态方法获取上述的静态成员变量
    //添加synchronized保证在多线程情况下运行正常
    public static synchronized Singleton3 getInstance() {
        //(4)调用该方法时再new,通过判断是否为空可控制只创建一个实例
        if(INSTANCE == null) {
            INSTANCE=new Singleton3();
        }
        return INSTANCE;
    }
}

注意:如果在多线程下,要防止多次创建实例,则在静态方法上添加synchronized,但其实我们只要在第一次调用时保证线程安全就可以,因此此方式的效率比较低,如果要提高效率,可以参考下述两种实现方式。

4、DCL懒汉式-双检索懒汉式

DCL懒汉式是为了保证多线程下运行正常,同时提高效率,也就是在静态方法中加锁之前判断是否已经创建了实例。同时静态变量使用volatile修饰

public class Singleton4 {
    //(2)声明静态变量为空
    private static volatile Singleton4 INSTANCE = null;//可见性,有序性
    //(1)构造私有
    private Singleton4(){
        System.out.println("private Singleton1()");
    }
    //(3)提供公共的静态方法获取上述的静态成员变量,调用该方法时再new
    public static Singleton4 getInstance() {
        //在加锁之前进行判断
        if(INSTANCE == null) {//一次检索
            synchronized (Singleton4.class){
                if (INSTANCE == null){//二次检索
                    INSTANCE=new Singleton4();
                }
            }
        }
        return INSTANCE;
    }
}

5、懒汉式内部类单例模式

使用内部类的方式可以保证线程安全,建议使用

public class Singleton5 {
    //构造私有
    private Singleton5(){
        System.out.println("private Singleton5()");
    }
    //创建内部类,在内部类中新建实例
    private static class Holder{
        static Singleton5 INSTANCE=new Singleton5();
    }
    private static Singleton5 getInstance(){
        return Holder.INSTANCE;
    }
}

二、单例模式在jdk中的体现

  • Runtime类是单例模式,饿汉式单例实现
  • System类中的有一个Console类型的cons变量,采用DCL懒汉式方式实现
  • Collections类中有大量单例模式实现,采用内部类懒汉式实现

标签:JDK,私有,private,INSTANCE,五种,static,单例,public
From: https://www.cnblogs.com/jiaxh/p/18024633

相关文章

  • 一个单例模式,没必要这么卷吧
    分享是最有效的学习方式。博客:https://blog.ktdaddy.com/老猫的设计模式专栏已经偷偷发车了。不甘愿做crudboy?看了好几遍的设计模式还记不住?那就不要刻意记了,跟上老猫的步伐,在一个个有趣的职场故事中领悟设计模式的精髓。还等什么?赶紧上车吧如果把系统软件比喻成江湖的话,那......
  • 设计模式浅析(五) ·单例模式
    设计模式浅析(五)·单例模式日常叨逼叨java设计模式浅析,如果觉得对你有帮助,记得一键三连,谢谢各位观众老爷......
  • JDK安装及卸载
    卸载jdk删除java的安装目录删除环境变量中的JAVA_HOME删除环境变量path中关于java的目录命令行输入java-version查看是否存在安装jdk百度搜索jdk8,找到下载地址下载电脑对应版本双击安装(**根据jdk安装路径****)配置环境变量->新建系统变量JAVA_HOME配置path变量:bin目......
  • centos7下安装的1.8jdk包
    1.安装目录选择你jdk需要放置的安装目录,我这里选择的是/usr/local/2.解压把在jdk官网下载的jdk包放入指定的文件夹下并解压,注意不同linux发行版下的jdk包是不一样的,不同系统下的包是不能使用的,比如我之前在centos7下安装的jdk包,在ubuntu18.04下就用不了。进入jdk目录下,解压命......
  • [设计模式]创建型模式-单例模式
    前言单例模式是最简单的一种模式。在Go中,单例模式指的是全局只有一个实例,并且它负责创建自己的对象。单例模式有减少内存和系统资源开销、防止多个实例产生冲突等优点。因为单例模式保证了实例的全局唯一性,并且只被初始化一次,所以比较适合全局共享一个实例,且只需要被初始化一次......
  • Azul JDK 8 G1 Evacuation Pause
    PSC:\zulu-8\bin>.\java.exe-versionopenjdkversion"1.8.0_402"OpenJDKRuntimeEnvironment(Zulu8.76.0.17-CA-win64)(build1.8.0_402-b06)OpenJDK64-BitServerVM(Zulu8.76.0.17-CA-win64)(build25.402-b06,mixedmode)2024-02-18T10:3......
  • JAVA基础-jdk8新特性
    Java8新特性:接口默认方法和静态方法JDK1.8打破了接口只提供了形式,而未提供任何具体实现这一限制,允许定义默认方法和静态方法。定义一个接口:packagecom.zgjt.design.defaults;importjava.util.function.Supplier;publicinterfaceAnimal{//接口默认方法,不必重......
  • JDK下载介绍及其选择
    1.JDK简介基本情况JDK是Java语言的软件开发工具包。JDK是整个Java开发的核心,它包括Java运行环境、Java基础类库和Java工具。版本情况按照维护情况分为non-LTS(短期)和LTS(长期)两种;对于短期支持版本(non-LTS)而言,Oracle只会提供6个月的支持维护;而对于长期支持......
  • dotnet asp.net seer agv 后台服务 单例注入
    常驻后台的数据导出服务/常驻后台的数据导出服务.csproj<ProjectSdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net7.0</TargetFramework><Nullable>enable</Nullable><ImplicitUsings>enable</Implic......
  • SpringBoot整合OSS中的设计模式----单例模式
    在SpringBoot项目中使用OSS存储上传的图片,需要配置OSS设置信息。避免对象的重复创建,确保一个类只有一个实例,并提供一个全局访问点来访问该实例,于是用到了单例模式,这里复习一下单例模式。单线程----懒汉式@Data@Component@ConfigurationProperties(prefix="aliyun.oss")pu......