单例模式Singleton

简介

单例模式就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。

举例

JDK里面的java.lang.Runtime 使用了单例模式(饿汉)

在这里插入图片描述

饿汉式(静态常量)

代码

//饿汉式(静态常量)
class SingleTone{

    //私有化构造器方法,防止new方式创建对象
    private SingleTone(){}

    //静态成员变量存放对象,并初始化
    private final static SingleTone singleton = new SingleTone();

    //提供public静态方法,返回实例对象
    public static SingleTone getInstance(){
        return singleton;
    }
}

讨论

优点:写法简单,在类装载的时候创建了对象,避免了线程同步问题。
缺点:在类装载的时候完成了实例化,没有达到Lazy Loading效果。如果从始至终都没有使用实例,则会	造成内存浪费。
结论:这种单例模式可用,但可能会照成内存浪费

饿汉式(静态代码块)

代码

//饿汉式(静态代码块)
class SingleTone{

    //私有化构造器方法,防止new方式创建对象
    private SingleTone(){}

    //静态成员变量存放对象
    private static SingleTone singleton;

    static {
        //静态代码块内部初始化实例
        singleton = new SingleTone();
    }

    //提供public静态方法,返回实例对象
    public static SingleTone getInstance(){
        return singleton;
    }
}

讨论

优点:写法简单,在类装载的时候创建了对象,避免了线程同步问题。
缺点:在类装载的时候完成了实例化,没有达到Lazy Loading效果。如果从始至终都没有使用实例,则会造成内存浪费。
结论:这种单例模式可用,但可能会照成内存浪费

懒汉式(线程不安全)

代码

//懒汉式(线程不安全)
class SingleTone{

    //私有化构造器方法,防止new方式创建对象
    private SingleTone(){}

    //静态成员变量存放对象,并初始化
    private static SingleTone singleton;

    //提供public静态方法,判断实例对象是否为null,返回实例对象
    public static SingleTone getInstance(){
        if(singleton == null){
            singleton = new SingleTone();
        }
        return singleton;
    }
}

讨论

优点:起到Lazy Loading效果,但只能在单线程下使用。
缺点:如果在多线程下,一个线程进入了 if(singleton == null)判断语句,但未来得及向下执行,另一个线程也通过了判断语句,这时会产生多个对象。所以是线程不安全的。
结论:实际开发中不能使用这种方式。

懒汉式(线程安全,同步方法)

代码

//懒汉式(线程安全,同步方法)
class SingleTone{

    //私有化构造器方法,防止new方式创建对象
    private SingleTone(){}

    //静态成员变量存放对象,并初始化
    private static SingleTone singleton;

    //提供public静态方法,判断实例对象是否为null,返回实例对象。添加同步机制实现线程安全
    public static synchronized SingleTone getInstance(){
        if(singleton == null){
            singleton = new SingleTone();
        }
        return singleton;
    }
}

讨论

优点:起到Lazy Loading效果,保证了线程安全。
缺点:效率太低,每个线程想要获取实例的时候都要排队,而实际上这个方法只执行一次代码实例化就够了。
结论:实际开发中不推荐使用这种方式。

懒汉式(双重检查)

代码

//懒汉式(双重检查)
class SingleTone{

    //私有化构造器方法,防止new方式创建对象
    private SingleTone(){}

    //静态成员变量存放对象
    private static volatile SingleTone singleton;

    //提供public静态方法,判断实例对象是否为null,返回实例对象。添加同步机制实现线程安全。
    public static SingleTone getInstance(){
        if(singleton == null){
            synchronized (SingleTone.class){
                if(singleton == null){
                    singleton = new SingleTone();
                }
            }
        }
        return singleton;
    }
}

讨论

优点:起到Lazy Loading效果,保证了线程安全,效率较高 。
结论:实际开发中推荐使用这种方式。

静态内部类

代码

//静态内部类
class SingleTone{

    //私有化构造器方法,防止new方式创建对象
    private SingleTone(){}

    //利用静态内部类在外部类加载的时候并不加载的特点保证了懒加载,同时利用内部类加载的时候进行实例化来保证了线程安全
    private static class SingletonInstance{
        private static final SingleTone INSTANCE = new SingleTone();
    }

    //提供public静态方法,判断实例对象是否为null,返回实例对象。
    public static SingleTone getInstance(){
        return SingletonInstance.INSTANCE;
    }
}

讨论

优点:起到Lazy Loading效果,保证了线程安全,效率较高 。
结论:实际开发中推荐使用这种方式。

枚举

代码

//枚举
enum SingleTone{
    INSTANCE;
    public void method(){
    }
}

讨论

优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建对象 。
结论:实际开发中推荐使用这种方式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值