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

7 种单例模式设计

作者头像
Tim在路上
发布2020-08-04 21:39:40
2410
发布2020-08-04 21:39:40
举报

饿汉式

// final 不允许被继承 
public final class Singleton {
    
    // 饿汉式,先new
    private static Singleton singleton = new Singleton();
    
    // 私有构造不允许外部 new
    private Singleton(){
        
    }
    
    public static Singleton getInstance(){
        return singleton;
    }
    
}

饿汉式的问题是 instance 在被 ClassLoader加载后很长时间才能在使用,如果类中的资源是重资源,那么就必须使用懒汉式

懒汉式

// final 不允许被继承
public final class Singleton {

    // 饿汉式,先new
    private static Singleton singleton = null;

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

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

问题是多线程下不能保证实例的唯一性。

懒汉式+ 同步

// 但是 只允许一个 线程 访问这个方法 ,效率就会很低

// final 不允许被继承
public final class Singleton {

    // 饿汉式,先new
    private static Singleton singleton = null;

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

    }

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

}

Double-check

//

// final 不允许被继承
public final class Singleton {

    // 饿汉式,先new
    // 不加 volatile 可能出现空指针异常 ,可能JVM指令的重排序
    private volatile static Singleton singleton = null;

    // 私有构造不允许外部 new
    private Singleton(){
    }
    // 双重校验,可以进入方法
    public static  Singleton getInstance(){
        if (singleton == null){
            synchronized(Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

Holder 实现静态的私有内部类

// final 不允许被继承
public final class Singleton {
    
    // 私有构造不允许外部 new
    private Singleton(){
         
    }

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

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

Singleton 类中,初始化过程中并不会创建 Singleton 的实例 ,只有当 Holder 类被主动引用的时候则会创建

枚举方式

枚举的方式不允许被继承,同时是线程安全的 ,只能被实例化一次

推荐使用枚举的方式

饿汉式

public enum  Singleton {

    INSTANCE;
    // 私有构造不允许外部 new
    private Singleton(){
        System.out.println("Instance will be init immediately");
    }
    //
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

// 懒加载

把枚举作为内部类进行懒加载

public class Singleton {

    private Singleton(){

    }

    private enum EnumHolder{
        INSTANCE;
        private Singleton instance;
        
        EnumHolder(){
            this.instance = new Singleton();
        }
        
        private Singleton getInstance(){
            return instance;
        }
    }
    
    public static Singleton getInstance(){
        return EnumHolder.INSTANCE.getInstance();
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 饿汉式
  • 懒汉式
  • 懒汉式+ 同步
  • Double-check
  • Holder 实现静态的私有内部类
  • 枚举方式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档