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

单例模式

原创
作者头像
HLee
修改2020-12-23 11:58:02
2380
修改2020-12-23 11:58:02
举报
文章被收录于专栏:房东的猫

定义:Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)

饿汉式:线程安全

描述:这种方式比较常用,但容易产生垃圾对象。

优点:没有加锁,执行效率会提高。

缺点:类加载时就初始化,浪费内存。

代码语言:javascript
复制
public final class Singleton {  // final不允许被继承

    private static Singleton instance = new Singleton(); // 在定义实例对象时,直接初始化

    private Singleton (){}  // 构造私有化,不允许外部new

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

总结:饿汉式的单例设计模式可以保证多线程下的唯一实例

懒汉式:线程不安全

描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。

代码语言:java
复制
public final class Singleton {  // final不允许被继承

    private static Singleton instance = null;  
    
    private Singleton (){}  // 构造私有化,不允许外部new
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}  

总结:getInstance在多线程环境下会导致instance被实例化一次以上,并不能保证单利的唯一性

懒汉式:线程安全

描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。

优点:第一次调用才初始化,避免内存浪费。

缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。

代码语言:javascript
复制
public final class Singleton {  

    private static Singleton instance;  
    
    private Singleton (){}  
    
    public static synchronized Singleton getInstance() {  // 加入同步控制,每次只有一个线程进入
       if (instance == null) {  
           instance = new Singleton();  
       }  
       return instance;  
    }  
} 

总结:采用懒汉式+数据同步方式既满足了懒加载又能够100%保证instance实例的唯一性,但是synchronized关键字关键字天生的排他性导致了getInstance方法只能在同一时刻被一个线程所访问,性能低下。

懒汉式:Double-Check

代码语言:javascript
复制
public final class Singleton {  

    private volatile static Singleton instance = null; // volatile防止指令重排序
    
    private Singleton (){}  
    
    public static Singleton getInstance() {   
       if (instance == null) {  
          synchronized (Singleton.class) {
             if (instance == null) {
                instance = new Singleton();  
             }
          } 
       }  
       return instance;  
    }  
} 

总结:Double-Check的方式提供了高效的数据同步策略

Holder方式

代码语言:javascript
复制
public final class Singleton {

    private Singleton() {}

    // 调用getInstance方法,事实上是获得Holder的instance静态属性
    public static Singleton getInstance() {
        return Holder.instance;
    }

    // 在静态内部类中持有Singleton的实例,并且可被直接初始化
    private static class Holder{
        private static Singleton instance = new Singleton();
    }
}

总结:Holder方式的单例设计模式是最好的设计之一,也是目前使用比较广的设计之一。

枚举方式

代码语言:javascript
复制
public final class Singleton {

    private Singleton() {}
    
    public static Singleton getInstance() {

        return EnumHolder.INSTANCE.getSingleton();
    }
    
    private enum  EnumHolder{

        INSTANCE;
        private Singleton instance;
        
        EnumHolder() {
            this.instance = new Singleton();
        }
        
        private Singleton getSingleton(){
            return instance;
        }
    }
}

总结:枚举类型不允许被继承,同样是线程安全的且只能被实例化一次

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 饿汉式:线程安全
  • 懒汉式:线程不安全
  • 懒汉式:线程安全
  • 懒汉式:Double-Check
  • Holder方式
  • 枚举方式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档