单例模式之四种实现

单例模式对大家来说应该都不陌生,不管是面试还是工作中大家都会避免不了要去使用,现在呢,咱们就来看看单例模式中最常见的四个模板是啥样的,分析其优点和缺点:

public class Singleton1 {
    /**
     * @category 饿汉模式 lazy loading
     * @author fengzi
     */

    private static class SingletonHolder{
        private static final Singleton1 INSTANCE = new Singleton1();
    }

    public Singleton1(){

    }
    public static final Singleton1 getInstance(){
        return SingletonHolder.INSTANCE;
    }

    public void test(){
        System.out.println("饿汉来啦!");
    }

    public static void main(String[] args) {
        Singleton1.getInstance().test();
    }
}
public class Singleton2 {
    /**
     * @author fengzi
     * @category 懒汉模式
     */

    private volatile static Singleton2 singleton;
    private Singleton2(){}

    public static Singleton2 getInstance(){
        if(singleton==null){
            synchronized(Singleton2.class){
                if(singleton==null){
                    singleton = new Singleton2();
                }
            }
        }
        return singleton;
    }

    public void test(){
        System.out.println("Haha!");
    }

    public static void main(String[] args) {
        Singleton2.getInstance().test();
    }

}

饿汉模式:在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快
懒汉模式:在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢

比较:饿汉模式由于在类初始化时候已经创建实例,因为不存在线程安全问题,而懒汉模式是在运行时创建实例,因此需要进行同步,来确保线程安全。

public enum Singleton3 {

    /**
     * @author fengzi
     * @category 枚举方式
     */
    INSTANCE;

    private Singleton3(){

    }

    public void test(){
        System.out.println("Haha!");
    }

    public static void main(String[] args) {
        Singleton3.INSTANCE.test();
    }

}

优点:
1. 自由序列化
2. 保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量);
3. 线程安全;

public class Singleton4 {
    /**
     * @author fengzi
     * 静态内部类
     */
    private static Singleton4 singleton = null;
    static class Nested {
        singleton = new Singleton4();
    }

    public Singleton4 getInstance(){
        return singleton;
    }

}

原理就是Java中静态内部类可以访问其外部类的成员属性和方法,同时,静态内部类只有当被调用的时候才开始首次被加载,因为java机制规定,内部类Nested 只有在getInstance()方法第一次调用的时候才会被加载(实现了lazy),而且其加载过程是线程安全的(实现线程安全)。内部类加载的时候实例化一次instance。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值