玩转单例模式,单例模式的主要作用是
分享于 点击 20882 次 点评:28
玩转单例模式,单例模式的主要作用是
Java中单例(Singleton)模式是一种广泛使用的设计模式。单例模式的主要作用是保证在Java程序中,某个类只有一个实例存在。一些管理器和控制器常被设计成单例模式。 单例模式的好处:- 能够避免实例对象的重复创建,不仅可以减少每次创建对象的时间开销,还可以节约内存空间;
- 能够避免由于操作多个实例导致的逻辑错误。
单例模式常见模式
饿汉模式
1.当类被加载时,静态变量会被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将被创建。因为类的加载过程天生是线程安全的,则此过程中创建的静态对象也是线程安全的。使用饿汉式单例,不会出现创建多个单例对象的情况,可确保单例对象的唯一性。 2. 类加载过程中,静态变量初始化过程中会将类的成员变量都创建,浪费空间。 3.如图例子,main方法中多线程使用getInstance方法拿到的静态对象,全都是同一个,符合单例要求。
懒汉模式
懒汉模式的单例,单线程安全版: 但此写法多线程下存在问题:会多次调用构造函数 并未按照懒汉式单例的设计发现有类的静态对象就直接返回此对象,而是多次调用了构造方法创建类的静态对象。原因是多线程调用getInstance方法时,有的线程判断空之后,已经进入了if大括号中,然后时间片被抢,别的线程判断也是空,创建完之后之前的线程拿到cpu直接创建了,导致多次调用构造函数创建。 解决前面饿汉式单例的问题:添加Synchronized关键字此方法问题是多个线程试图调用getInstance方法进行判断时都要进行锁定,太降低效率了。缩小加锁范围
实际验证在if内加锁的结果和理论一样 多线程还是会创建多个对象,synchronized关键字放在if里面没有办法解决问题。DCL懒汉式单例(双重检验Double-Checking-Locking)
双重检验的懒汉式单例,注意给静态对象增加volatile关键字,因为构造函数中的new操作不是原子性操作。静态内部类
核心:就是将前面类的静态变量的生成过程,即new静态常量的过程放入了静态内部类中, 由于静态内部类是在使用时才加载,就有了懒加载的效果,做到了懒汉式单例的效果,但又不存在加锁的问题。单例饿汉、懒汉、内部静态类方法总结:
- 三种方式都是包含三个部分:public的getInstance方法(给外部提供类的单例对象) 类的静态对象获取 private的类构造器(确保单例)
- 都是从getInstance获取单例对象,饿汉是直接返回类的静态常量对象,懒汉是要用双重检验锁 然后返回类的静态常量,静态内部类是直接返回类的静态常量对象
- 静态常量的生成 饿汉式直接final static 修饰一个对象获取new类对象 懒汉式是private static volatile声明了一下 然后在getInstance方法中new了 最后返回new的对象 放入方法中实现了延迟加载 静态内部类是搞了一个内部类,把懒汉的那一句声明和实例化都放到静态内部类中了 用静态内部类实现延迟加载
- 私有化构造器保证单例,都是在new对象的时候使用到。
用户点评