01-01-JAVA基础-02-设计模式-03-创建型模式-01-单例模式

 

八种单例模式对比

1.什么是单例模式?

单例模式就是让一个类在系统内存中只有一个实例对象,通常用一个静态方法提供。

 

2.为什么要用单例模式?

对于频繁创建和销毁的对象,以及创建重量级对象,耗时多的对象,都会增加内存开销,通过单例模式可以提高系统性能,节约内存资源。

 

3.八种设计模式对比

Method1:饿汉式(静态常量法)

 

public class Singleton{

    private Singleton() {}

    private static final Singleton s = new Singleton();

    public static Singleton getInstance() {

        return s;

    }

}

 

评论:该方式通过静态常量的方式提供实例,方法简洁,保证了线程安全,但是没有做到Lazy loading(懒加载),如果没有调用获取实例的方法,同时又加载了这个类(加载这个类的情况有很多),创建对象就造成了资源浪费,如果能确保一定用到这个实例,该方法推荐使用,JDK中Runtime类就是通过这种方法获取实例。

 

Method2:饿汉式(静态代码块)

public class Singleton{

    private Singleton() {}

    private static Singleton s;

    static{

         s = new Singleton();

    }

    public static Singleton getInstance() {

        return s;

    }

}

 

评论:该方法通过静态代码块的方法获得实例,静态代码块在类加载时执行,优缺点同Method1。

 

Method3:懒汉式-1

public class Singleton{

    private Singleton() {}

    private static Singleton s;

    public static Singleton getInstance() {

        if (s == null) {

            s = new Singleton();

        }

        return s;

    }

}

 

 

评论:该方式做到了懒加载,单线程使用没有问题;但是在多线程情况下,可能会创建多个实例,不能保证线程安全,不可用。

 

Method4:懒汉式-2

public class Singleton{

    private Singleton() {}

    private static Singleton s;

    public static synchronized Singleton getInstance() {

        if (s == null) {

            s = new Singleton();

        }

        return s;

    }

}

 

评论:该方式通过同步方法获取实例,保证了线程同步和懒加载,但是每次获取实例都要调用同步方法,造成效率低下,但从效率上不推荐使用。

 

Method5:懒汉式-3

public class Singleton{

    private Singleton() {}

    private static Singleton s;

    public static Singleton getInstance() {

        if (s == null) {

            synchronized (Singleton.class) {

                s = new Singleton();

            }

        }

        return s;

    }

}

 

评论:该方式通过同步代码块获取实例,保证了懒加载,但是不能保证线程同步,多线程情况下不可用。

 

Method6:双重检查

public class Singleton{

    private Singleton() {}

    private static volatile Singleton s = null;

    public static Singleton getInstance() {

        if (s == null) {

            synchronized (Singleton.class) {

                if (s == null) {

                    s = new Singleton();

                }

            }

        }

        return s;

    }

}

 

评论:该方式实例变量用volatile 修饰,在变化时立马同步到主内存,保证了线程同步、懒加载,也解决了效率问题,推荐使用。

 

Method7:静态内部类

public class Singleton{

    private Singleton() {}

    static class Single {

        private static final  Singleton s = new Singleton();

    }

    public static Singleton getInstance() {

        return Single.s;

    }

}

 

评论:该方式借助静态内部类的优势,加载Singleton的时候不加载Single ,保证了懒加载;Single类在使用的时候才加载,且只加载一次,保证了线程同步和效率问题,推荐使用。

 

Method8:枚举

enum Singleton{

    INSTANCE;

}

 

评论:该方式通过Singleton.INSTANCE得到实例,实例唯一,线程安全,推荐使用。

 

总结:

1.实现层面,以上八种方法在单线程下都是可行的;

2.多线程层面,Method3和Method5不可用;

3.效率层面,同步方法Method3不推荐;

4.懒加载层面,两种饿汉式Method1,2不推荐;

5.多方面考虑Method6,7,8推荐使用;


作者:Darren

电话:15110448224

QQ:603026148

以上内容归Darren所有,如果有什么错误或者不足的地方请联系我,希望我们共同进步。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从码农到码到成功

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值