zl程序教程

您现在的位置是:首页 >  后端

当前栏目

单例模式作用特点及常见的单例模式分析(6种单例模式分析)

模式 作用 常见 特点 单例 模式分析
2023-06-13 09:17:11 时间

单例模式:

  1. 即在整个生命周期中,对于该对象的生产始终都是一个,不曾变化。
  2. 保证了一个类仅有一个实例,并提供一个访问它的全局访问点。

作用:

  1. 在要求线程安全的情况下,保证了类实例的唯一性,线程安全。
  2. 在不需要多实例存在时,保证了类实例的单一性。不浪费内存。

特点:

  1. 公有的方法获取实例,
  2. 私有的构造方法,
  3. 私有的成员变量。

一,饿汉式 * @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静态变量,是最好的单例模式之一

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 基于枚举类线程安全 * 枚举类型不允许被继承,同样线程安全的,且只能被实例化一次。

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();
    }