前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【设计模式】单例模式

【设计模式】单例模式

作者头像
后端码匠
发布2023-02-27 09:15:58
2880
发布2023-02-27 09:15:58
举报
文章被收录于专栏:后端码匠

单例模式

单例模式(Singleton Pattern):确保一个类有且只有一个实例,并提供一个全局访问点。

在开发中,很多时候有一些对象其实我们只需要一个,例如:线程池(threadpool)缓存(cache)默认设置注册表(registry)日志对象等等,这个时候把它设计为单例模式是最好的选择。

Java中单例模式是一种广泛使用的设计模式,单例模式有很多好处,它能够避免实例对象的重复创建,不仅可以减少每次创建对象的时间开销,还可以节约内存空间(比如spring管理的无状态bean);还能够避免由于操作多个实例导致的逻辑错误。如果一个对象有可能贯穿整个应用程序,而且起到了全局统一管理控制的作用,那么单例模式也许是一个值得考虑的选择。

懒汉模式(线程不安全)

代码语言:javascript
复制
/**
 * @author inke219223m
 */
public class Singleton {

    private static Singleton instance;
    private Singleton_01() {}

    public static Singleton getInstance() {
        if (null != instance) return instance;
        instance = new Singleton();
        return instance;
    }

}

懒汉模式(线程安全)

此模式保证了线程安全,但是由于把锁加到了方法上,所有的访问都因为需要锁占用导致资源浪费。

代码语言:javascript
复制
/**
 * @author inke219223m
 */
public class Singleton {

    private static Singleton instance;
    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (null != instance) return instance;
        instance = new Singleton();
        return instance;
    }

}

双重校验锁(懒汉)

代码语言:javascript
复制
/**
 * @author inke219223m
 */
public class Singleton {
    
    private volatile static Singleton singleton;  
    private Singleton (){}  
    
    public static Singleton getSingleton() {  
     if (singleton == null) {  
         synchronized (Singleton.class) {  
          // 注意此处还得有次判空~
          if (singleton == null) {  
              singleton = new Singleton();  
          }  
         }  
     }  
     return singleton;  
    }
    
}  

饿汉模式(线程安全)

此模式在程序启动时直接运行加载,后续有外部需要使用的时候获取即可。无论程序中是否用到这样的类都会在程序启动之初创建。(这也是它的缺点,无意义地占用内存)

代码语言:javascript
复制
/**
 * @author inke219223m
 */
public class Singleton {

    private static Singleton instance = new Singleton();
    public Singleton(){};

    public static Singleton getInstance() {
        return instance;
    }

}

饿汉(变种)

代码语言:javascript
复制
/**
 * @author inke219223m
 */
public class Singleton {  
    
    private static Singleton instance = null;  
    
    static {  
      instance = new Singleton();  
    }  
    
    private Singleton (){}  
    
    public static Singleton getInstance() {  
     return instance;  
    }
    
} 

类的静态内部类

使用类的静态内部类实现的单例模式,保证了线程安全,也保证了懒加载,也不会因为加索的方式耗费性能,这主要是因为JVM虚拟机保证多线程并发访问正确性,一个类的构造方法在多线程环境可以被正确加载(推荐使用)。

代码语言:javascript
复制
/**
 * @author inke219223m
 */
public class Singleton {

    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
    
}

CAS[AtomicReference](线程安全)

Java并发库提供了很多原子类支持并发访问数据安全性,AtomicReference可以封装引用一个实例,支持并发访问。使用CAS的好处就是不需要使用传统的加锁方式保证线程安全,而是依赖于CAS的忙等算法,依赖于底层硬件的时间。相对于其他锁的实现没有线程的切换和组测也就没有了额外的开销,可以支持比较大的并发性,缺点就是如果一直没有获取到将会处于死循环中。

代码语言:javascript
复制
/**
 * @author inke219223m
 */
public class Singleton {

    private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();

    private static Singleton instance;

    private Singleton() {
    }

    public static final Singleton getInstance() {
        for (; ; ) {
            Singleton instance = INSTANCE.get();
            if (null != instance) return instance;
            INSTANCE.compareAndSet(null, new Singleton());
            return INSTANCE.get();
        }
    }

}

枚举单例(线程安全)

这种方式在功能上与共有域方法相近,但更加简洁,无偿提供串行化机制,绝对防止对此实例化(但是在继承场景下不可用)。

代码语言:javascript
复制
/**
 * 单元素的枚举类型已经成为实现Singleton的最佳方法
 * @author inke219223m
 */
public enum Singleton {

    INSTANCE;

    public void doSomething() {
        System.out.println("doSomething");
    }
}

class MainTest {

    public static void main(String[] args) {
        Singleton.INSTANCE.doSomething();
    }

}

项目地址:https://gitee.com/codingce/codingce-leetcode

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端码匠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单例模式
    • 懒汉模式(线程不安全)
      • 懒汉模式(线程安全)
        • 双重校验锁(懒汉)
      • 饿汉模式(线程安全)
        • 饿汉(变种)
      • 类的静态内部类
        • CAS[AtomicReference](线程安全)
          • 枚举单例(线程安全)
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档