设计模式——单例模式

单例模式

  1. 懒汉模式

    // 建议直接了解双重校验锁版本
    public class SingletonDemo {
        private static SingletonDemo instance;
        private SingletonDemo(){}
        public static synchronized SingletonDemo getInstance(){
            if(instance==null){
                instance=new SingletonDemo();
            }
            return instance;
        }
    }
  2. 静态类内部加载

    public class SingletonDemo {
        // 类加载的时候就会初始化
        private static class SingletonHolder{
            private static SingletonDemo instance=new SingletonDemo();
        }
        private SingletonDemo(){
            System.out.println("Singleton has loaded");
        }
        public static SingletonDemo getInstance(){
            return SingletonHolder.instance;
        }
    }
  3. 枚举方法

    enum SingletonDemo{
        INSTANCE;
        public void otherMethods(){
            System.out.println("Something");
        }
    }
    // 调用 SingletonDemo.INSTANCE.otherMethods();

     

  4. 双重校验锁

    public class SingletonDemo {
        // 这里volatile的作用是防止在instance = SingletonDemo()的时候指令重排列
        // 1. 给instance 分配内存空间
        // 重排列后 3.将给singleton对象指向分配的内存空间(此时singleton才不为null) 
        // 2. 调用 Singleton 的构造函数来初始化成员变量
        // 因为在3完成后,instance已经不==空了,这时候b线程进来就能直接返回instance
        // Synchronized锁代码块
        private volatile static SingletonDemo instance;
        private SingletonDemo(){
            System.out.println("Singleton has loaded");
        }
        public static SingletonDemo getInstance(){
            if(instance==null){
                synchronized (SingletonDemo.class){
                    if(instance==null){
                        instance=new SingletonDemo();
                    }
             }
            }
            return instance;
        }
    }

    单例模式实现的关键点:让对象在内存中只能有一份

    1. 可以使用静态类,将对象的代码放在虚拟机栈中;

    2. 可以在new 对象的时候判断对象是否已经存在,如果存在即返回对象即可,否则可以创造对象;如果是多线程环境还需要在判断对象不存在的时候,防止其他线程同时判断并创造对象,所以需要给对象上锁和保持可见性;

    3. 可以让对象在创建时就自己完成对象的创建;

    静态类和单例的区别

    1. 单例可以继承和被继承,方法可以被重写,而静态方法不可以。

    2. 静态方法中产生的对象会在执行后被释放,进而被GC清理,不会一直存在于内存中。

    3. 静态类会在第一次运行时初始化,单例模式可以延迟加载。

    4. 基于2, 3条,由于单例对象往往存在于DAO层(例如sessionFactory),如果反复的初始化和释放,则会占用很多资源,而使用单例模式将其常驻于内存可以更加节约资源。

    5. 静态方法有更高的访问效率。

    6. 单例模式很容易被测试。

    几个关于静态类的误解:

    误解一:静态方法常驻内存而实例方法不是。

    实际上,特殊编写的实例方法可以常驻内存,而静态方法需要不断初始化和释放。

    误解二:静态方法在堆(heap)上,实例方法在栈(stack)上。

    实际上,都是加载到特殊的不可写的代码内存区域中。

    静态类和单例模式情景的选择:

    情景一:不需要维持任何状态,仅仅用于全局访问,此时更适合使用静态类。

    情景二:需要维持一些特定的状态,此时更适合使用单例模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值