设计模式学习笔记(6)——单例模式

版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/weixin_36904568/article/details/89923575

1. 定义

确保类中只有一个实例,由自己创建,并且提供一个全局访问点

2. 使用

(1)即时实现(饿汉式)——空间换时间

  • 私有构造器
  • 私有静态变量:初始化为具体对象,记录唯一实例
  • 公共静态构造方法
    • 返回唯一实例
package SingletonPattern;

/**
 * 即时单例
 */
public class ImmediatelySingletion {

    //一开始就创建
    private static ImmediatelySingletion singletion = new ImmediatelySingletion();

    private ImmediatelySingletion(){}

    public static ImmediatelySingletion getInstance(){
        return singletion;
    }
}

(2)延时实现(懒汉式)——时间换空间

  • 私有构造器
  • 私有静态变量:初始化为空值,记录唯一实例
  • 公共静态构造方法:检查是否存在实例
    • 创建唯一实例
    • 返回唯一实例
package SingletonPattern;

/**
 * 延时实现
 */
public class DelayedSingleton {

    //暂未初始化
    private static DelayedSingleton singleton;

    private DelayedSingleton(){}

    public static DelayedSingleton getInstance(){
        if (singleton == null)
            singleton = new DelayedSingleton();
        return singleton;
    }

}

(3)枚举

单元素的枚举类型已经成为实现Singleton的最佳方法。用枚举来实现单例非常简单,只需要编写一个包含单个元素的枚举类型即可。

package SingletonPattern;

/**
 * 枚举类
 */
public enum  EnumSingleton {

    //枚举单元素
    singleton;

    public void operation(){
        System.out.println("枚举类的业务逻辑");
    }
}

3. 多线程

(1)即时实现

(2)延迟实现

使用synchorized修饰公共静态构造方法

 public static synchronized DelayedSingleton getInstance(){
        if (singleton == null)
            singleton = new DelayedSingleton();
        return singleton;
    }

特点:效率低,在每次创建实例的时候都会同步

(3) 双重检查加锁

  • 使用volatile修饰私有静态变量
  • 公共静态构造方法
    • 第一重检查: 检查是否存在实例
    • 第二重检查:进入同步块过后,再次检查实例是否存在
      • 创建唯一实例
    • 返回唯一实例
package SingletonPattern;

/**
 * 双重加锁检查
 */
public class DuplicationCheck {

    //不会被本地线程缓存
    private static volatile DuplicationCheck singleton;

    private DuplicationCheck(){}

    public static DuplicationCheck getInstance(){
        if (singleton == null){
            synchronized (DuplicationCheck.class){
                if (singleton == null) 
                    singleton = new DuplicationCheck();
            }
        }
        return singleton;
    }

}

特点:volatile关键字可能会屏蔽掉虚拟机中一些必要的代码优化,效率较低

(4) Lazy initialization holder class模式

类级内部类:由static修饰的成员式内部类
多线程缺省同步锁:由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时会自动同步

package SingletonPattern;

/**
 * 通过静态内部类创建对象
 */
public class StaticInnerClass {

    private StaticInnerClass(){}

    /**
     * 被调用时才会加载,由JVM保护线程安全
     */
    private static class holderClass{
        private static StaticInnerClass singleton = new StaticInnerClass();
    }

    public static StaticInnerClass getInstance(){
        return holderClass.singleton;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_36904568/article/details/89923575