Java设计模式之单例模式简单解析

 更新时间:2023年12月16日 09:41:52   作者:小晨想好好学习  
这篇文章主要介绍了Java设计模式之单例模式简单解析,单例模式的优点在于在内存中某个类只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例,避免对资源的多重暂用,需要的朋友可以参考下

单例模式的优缺点

优点:

  • 在内存中某个类只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
  • 避免对资源的多重暂用

缺点: 没有接口,不能继承

单例模式的几种实现方式

1、饿汉式(线程安全)

类加载时就初始化实例,避免了多线程同步问题,天然线程安全。

为什么饿汉式是线程安全的? 类加载的方式是按需加载,且只加载一次。因此,在上述单例类被加载时,就会实例化一个对象并交给自己的引用,供系统使用,即在线程访问单例对象之前,其就已经创建好了。线程每次都只能拿到这个唯一的对象。因此,饿汉式单例天生就是线程安全的。

class Singleton{
    //1、私有化构造器,这样外部就不能通过构造器来创建对象
    private Singleton(){
    }
    //2、本类内部创建对象实例
    private final static Singleton instance = new Singleton();
    //3、对外提供一个共有的静态方法,返回对象实例
    public static Singleton getInstance(){
        return instance;
    }
}

2、饿汉式(静态代码块方式)

class Singleton{
    //1、私有化构造器,这样外部就不能通过构造器来创建对象
    private Singleton(){
    }
    //2、本类内部创建对象实例
    private static Singleton instance;
    //3、在静态代码块中创建单例对象
    static {
        instance = new Singleton();
    }
    //4、对外提供一个共有的静态方法,返回对象实例
    public static Singleton getInstance(){
        return instance;
    }
}

3、懒汉式(线程不安全)

实例对象在第一次被调用的时候才真正构建的,而不是程序一启动就会自动构建。这种实现最大的问题就是不支持多线程,因为没有加锁 ,多线程场景下不要使用,因为可能会产生多个对象,不再是单例

class Singleton{
    private static Singleton instance;
    private Singleton(){};
    //提供一个静态的公有方法,当使用到该方法时,才会去创建instance
    public static Singleton getInstance(){
        if(instance==null){
            instance = new Singleton();
        }
        return instance;
    }
}

4、懒汉式+锁 实现多线程安全的单例模式

每次获取实例时,也需要等待其他线程的锁释放,效率低

class Singleton{
    private static Singleton instance;
    private Singleton(){};
    //提供一个静态的公有方法,当使用到该方法时,才会去创建instance
    public static synchronized Singleton getInstance(){
        if(instance==null){
            instance = new Singleton();
        }
        return instance;
    }
}

5、double-check locking实现单例模式

多个线程只在创建实例的时候加锁实现同步

class Singleton{
    // volatile: 轻量级的synchronized, 由它修饰的变量在发生变化后会立即刷新到主存
    private static volatile Singleton instance;
    private Singleton(){};
    public static Singleton getInstance(){
        if(instance==null){
            synchronized (Singleton.class){
                if(instance==null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

【注意】instance为什么需要采⽤ volatile 关键字修饰?

instance采⽤ volatile 关键字修饰也是很有必要的,在上述代码中有下面这一句代码

instance= SingletonDCL();

其实是分为三步执⾏的:

1.为 instance 分配内存空间

2. 初始化 instance

3. 将 instance指向分配的内存地址

但是由于 JVM 具有指令重排的特性,执⾏顺序有可能变成 1->3->2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致⼀个线程获得还没有初始化的实例。

例如,线程A 执⾏了 1 和3,此时线程B调⽤ getInstance() 后发现 instance不为空,因此返回instance,但此时instance还未被初始化,使⽤ volatile 可以禁⽌ JVM 的指令重排 ,保证在多线程环境下也能正常运⾏。

到此这篇关于Java设计模式之单例模式简单解析的文章就介绍到这了,更多相关Java的单例模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • idea中引入了gb2312编码的文件的解决方法

    idea中引入了gb2312编码的文件的解决方法

    这篇文章主要介绍了idea中引入了gb2312编码的文件的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java的WeakHashMap源码解析及使用场景详解

    Java的WeakHashMap源码解析及使用场景详解

    这篇文章主要介绍了Java的WeakHashMap源码解析及使用场景详解,Map本身生命周期很长,需要长期贮留内存中,但Map中的Entry可以删除,使用时可以从其它地方再次取得,需要的朋友可以参考下
    2023-09-09
  • 详解Huffman编码算法之Java实现

    详解Huffman编码算法之Java实现

    Huffman编码是一种编码方式,常用于无损压缩。本文只介绍用Java语言来实现该编码方式的算法和数据结构。有兴趣的可以了解一下。
    2016-12-12
  • java控制线程运行

    java控制线程运行

    这篇文章主要介绍了java控制线程运行,需要的朋友可以参考下
    2014-04-04
  • springboot2.x只需两步快速整合log4j2的方法

    springboot2.x只需两步快速整合log4j2的方法

    这篇文章主要介绍了springboot2.x只需两步快速整合log4j2的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • SpringBoot3整合SpringCloud启动后nacos报错获取不到配置、无法注册服务的解决方案

    SpringBoot3整合SpringCloud启动后nacos报错获取不到配置、无法注册服务的解决方案

    文章介绍了如何使用Spring Boot 3.3.4和Spring Cloud 2023.0.3搭建微服务项目,并解决与Nacos服务注册发现和配置中心的集成问题,主要解决了依赖版本不兼容、配置文件导入问题及服务注册失败等问题,感兴趣的朋友跟随小编一起看看吧
    2025-02-02
  • Java网络编程UDP实现消息发送及聊天

    Java网络编程UDP实现消息发送及聊天

    这篇文章主要为大家详细介绍了Java网络编程UDP实现消息发送及聊天,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Springboot Caffeine本地缓存使用示例

    Springboot Caffeine本地缓存使用示例

    这篇文章主要介绍了Springboot Caffeine本地缓存使用示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • flowable动态创建多级流程模板实现demo

    flowable动态创建多级流程模板实现demo

    这篇文章主要为大家介绍了flowable动态创建多级流程模板实现demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • JProfiler11使用教程之JVM调优问题小结

    JProfiler11使用教程之JVM调优问题小结

    这篇文章主要介绍了JProfiler11使用教程之JVM调优,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03

最新评论