单例模式:面试
做用:编程
特色:安全
一,饿汉式
* @Description 饿汉式单例
* 饿汉式单例关键在于singleton做为类变量而且直接获得了初始化,即类中全部的变量都会被初始化
* singleton做为类变量在初始化的过程当中会被收集进<clinit>()方法中,该方法可以百分之百的保证同步,
* 可是由于不是懒加载,singleton被加载后可能很长一段时间不被使用,即实例所开辟的空间会存在很长时间
* 虽然能够实现多线程的惟一实例,但没法进行懒加载;多线程
package com.liruilong.singleton; /** * @Author: Liruilong * @Date: 2019/7/20 17:55 */ // final 不容许被继承 public final class Singleton { // 实例变量 private byte[] bate = new byte[1024]; // 私有的构造函数,即不容许外部 new private Singleton(){ } private static final Singleton singleton1 = new Singleton(); public static Singleton getInstance1(){ return singleton1; }
* @Description 懒汉式单例模式
* 能够保证懒加载,可是线程不安全
* 当有两个线程访问时,不能保证单例的惟一性并发
package com.liruilong.singleton; /** * @Author: Liruilong * @Date: 2019/7/20 17:55 */ // final 不容许被继承 public final class Singleton { // 实例变量 private byte[] bate = new byte[1024]; // 私有的构造函数,即不容许外部 new private Singleton(){ } private static Singleton singleton =null;
public static Singleton getInstance(){ if (singleton == null) { singleton = new Singleton(); } return singleton; }
三,懒汉式加同步方法
* @Description 懒汉式+同步方法单例模式
* 即能保证懒加载,又能够保证singleton实例的惟一性,可是synchronizeed关键字的排他性致使
* getInstance0()方法只能在同一时间被一个线程访问。性能低下。函数
package com.liruilong.singleton; /** * @Author: Liruilong * @Date: 2019/7/20 17:55 */ // final 不容许被继承 public final class Singleton { // 实例变量 private byte[] bate = new byte[1024]; // 私有的构造函数,即不容许外部 new private Singleton(){ } private static Singleton singleton =null;
public static synchronized Singleton getInstance0(){ if (singleton == null) { singleton = new Singleton(); } return singleton; }
四,双重效验锁单例
* @Description 双重校验锁单例(Double-Check)+Volatile
* 对懒汉-同步方法的改进,当有两个线程发现singleton为null时,只有一个线程能够进入到同步代码块里。
* 即知足了懒加载,又保证了线程的惟一性
* 不加volition的缺点,有时候可能会报NPE,(JVM运行指令重排序)
* 有可能实例对象的变量未完成实例化其余线程去获取到singleton变量。
* 未完成初始化的实例调用其方法会抛出空指针异常。性能
package com.liruilong.singleton; /** * @Author: Liruilong * @Date: 2019/7/20 17:55 */ // final 不容许被继承 public final class Singleton { // 实例变量 private byte[] bate = new byte[1024]; // 私有的构造函数,即不容许外部 new private Singleton(){ } private static volatile Singleton singleton2 = null;
public static Singleton getInstance4() { if (singleton2 == null){ synchronized (Singleton.class){ if (singleton2 ==null){ singleton2 = new Singleton(); } } } return singleton2; }
五,静态内部类单例
* @Description 静态内部类的单例模式
* 在Singleton类初始化并不会建立Singleton实例,在静态内部类中定义了singleton实例。
* 当给静态内部类被主动建立时则会建立Singleton静态变量,是最好的单例模式之一
ui
package com.liruilong.singleton; /** * @Author: Liruilong * @Date: 2019/7/20 17:55 */ // final 不容许被继承 public final class Singleton { // 实例变量 private byte[] bate = new byte[1024]; // 私有的构造函数,即不容许外部 new private Singleton(){ } private static class Singtetons{
private static Singleton SINGLETON = new Singleton(); /* static { final Singleton SINGLETON = new Singleton(); }*/ } public static Singleton getInstance2(){ return Singtetons.SINGLETON; }
* @Description 基于枚举类线程安全
* 枚举类型不容许被继承,一样线程安全的,且只能被实例化一次。this
package com.liruilong.singleton; /** * @Author: Liruilong * @Date: 2019/7/20 17:55 */ // final 不容许被继承 public final class Singleton { // 实例变量 private byte[] bate = new byte[1024]; // 私有的构造函数,即不容许外部 new private Singleton(){ } private enum Singtetonss { SINGTETONSS; //实例必须第一行,默认 public final static修饰 private Singleton singleton; Singtetonss() { //构造器。默认私有 this.singleton = new Singleton(); } public static Singleton getInstance() { return SINGTETONSS.singleton; } } public static Singleton getInstance3(){ return Singtetonss.getInstance(); }
本来是我笔记里的,摘了出来,面试的时候看,spa