菜鸟日记:复盘单例模式OOP

1.单例模式定义?

顾名思义就是在整个运行时域,一个类只有一个实例对象。

2.为什么使用单例设计模式?

因为有的类型的实例对象的创建和销毁对资源来说消耗不大,有的类庞大而且复杂,如果频繁的 创建和销毁对象,并且这些对象是完全可以复用的,那么将会造成一些不必要的性能浪费。

例子:比如现在要写一个访问数据库的demo,而创建数据库链接对象是一个耗资源的操作,并且数据库 链接是完全可以复用的,那么可以将这个对象设计成单例的,这样只需要创建一次并且重复使用这个对象就行了。而不需要每次访问数据库都去创建一个链接对象。

3.在Java中,如何实现单例模式呢?

三点需要考虑:是否线程安全?是不是懒加载?能不能通过反射破坏?

public class Singleton {
    //第一种:双检锁写法,有一点复杂
    //使用volatile就能组织作用在instance上的指令重排问题
    private volatile static Singleton singleton;
    private Singleton(){ }//构造器私有,其他类没有办法通过new来构造这个Singleton实例
//    private static Singleton instance=null;//初始化对象为null
    //加锁,synchronized,才能线程安全,但是每次在获取对象时都要进行同步操作,对性能影响非常大,不可取
    public static  Singleton getInstance() {//其他类中需要使用Singleton对象的话只能通过调用getInstance方法
        //在getInstance方法中,首先判断instance是否被构造过,如果构造过就直接使用,若没有就当场构造
        //实例对象是第一次被调用的时候才真正构建的,这种之后构建的方式就叫做懒加载
        //懒加载的好处:有的对象构建开销是比较大的,假如这个对象在项目启动时就构建,万一从来都没有被调用过,那就比较浪费
        //真正使用了才去创建是更加合理的
        //线程不安全,执行判断语句时,可能有多个不同线程同时进入,会执行多次
        if (singleton == null){
            synchronized (Singleton.class){
                if (singleton == null){
                    singleton=new Singleton();
                }
            }
        }
        return singleton;
        //只需要在构建对象时同步,而直接使用对象的时候就没有必要同步
        //对象进行两次判空的操作叫做双检锁,是一种常见的同步线程手段
        /*
        happens-before原则:1.程序顺序原则2.锁定原则3.volatile变量原则4.线程启动规则
                            5.线程结束原则6.中断原则7.终结器原则8.传递性规则
         */
    }
}
public class Singleton1 {
    //第二种:静态内部类,在程序启动的时候不会加载,只有第一次被调用的时候才会加载
    //此方法巧妙运用了Jdk加载机制的特性来 实现懒加载
    private static class SingletonHolder{
        private static final  Singleton1 INSTANCE =new Singleton1();
    }
    private Singleton1(){}
    public static final Singleton1 getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

//上面几种方式都是可以通过反射来破坏的,但是能反射操作是一种人为的主动操作,只有故意那样操作才会破坏,所以只考虑第一点和第二点是否满足就可以

//对于枚举类型,不能通过反射来获取枚举对象,反射无法获取到它的构造器,因此反射就不能破坏枚举类型的单例,枚举类型本身可以保证线程安全,但是不属于懒加载,它在程序启动之初,就已经把内部的实例完全构建好 来提供给使用者了。目前没有完全满足三个条件的单例写法。第三点基本可以不用考虑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值