Java 实现单例(Singleton)模式

单例模式(Singleton)解释

只生成一个实例的的类是实现了单例(Singleton)模式的类型。

版本一:单线程环境

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

只有当上面代码中的 instance静态变量为空的时候,才会去创造一个实例,同时构造函数定义为私有,这样就确保Singleton这个类只创建了一个实例

版本二:多线程环境 (同步延迟加载)

版本一可以在单线程中正常运行,但多线程就出现了问题。假想现在有两个线程同时运行判断语句instance == null,并且此时instance还没有创建,那么两个线程都会创建一个实例,此时这个类就不满足单例模式了。当然,如果有同时又更多的线程执行判断语句instance == null,并且此时instance还没有创建,那么会创建更多的实例。

为了保证在多线程的环境下只能得到类的一个实例,我们在getInstance()方法上加一个同步关键词synchronized ,这样可以保证在多个线程同时访问getInstance()方法时,只有一个线程能否进入函数体,其他线程等待,当第一个线程执行完函数体后,第二线程进入,剩余线程等待…..,这样就保证类只有一个实例

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

版本三:多线程环境(进阶1 双重检测同步延迟加载 )

版本二固然可以在多线程环境下正常运行,但是效率不高。考虑如下的情况:当instance 已经被初始化后,有多个线程访问getInstance()方法,但是由于线程同步锁的原因,线程只能一个接一个的执行getInstance()方法,这期间线程的等待就浪费了许多时间。为了解决这个问题就出现了如何下解决方案,现在只有当instancenull的时候才会加锁操作,否则无需加锁操作。

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

版本四:多线程环境(进阶2 非延迟加载单例类 )

为了让代码更加优雅,简洁,同时健壮性很好,就出现了非延迟加载单例类,又被称之为饿汉式.

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

这里的instance 实例在第一次使用Singleton这个类型的时候自动初始化,假设Singleton类中还有其他的静态函数,那么调用该静态函数也会初始化instance 变量,这就导致过早的初始化instance 变量,从而降低了内存的使用效率。

版本五:多线程环境(进阶3 使用内部类实现延迟加载 )

public class Singleton{
    private Singleton(){}
    public static Singleton getInstance() {
        return Holder.instance;
    }
    private static class Holder {
        static Singleton instance = new Singleton();
    }
}

上面代码在Singleton类中定义了一个私有类Holder ,当第一次使用到Holder 类型时,会创建instance ,而Holder 类型只在getInstance()方法中使用到,如果我们不调用getInstance(),就不会触发instance的创建操作,从而做到真正的按需创建。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值