Java快速开发学习

锁清秋

单例模式

一、使用单例模式的原因和方法

  1. 原因:多个线程要操作同一对象,要保证对象的唯一性
  2. 方法:实例化过程中只实例化一次

    二、单例模式三个主要特点:

  3. 构造方法私有化;

  4. 实例化的变量引用私有化;[ 有一个实例化的过程(只有一次),产生实例化对象 new ]
  5. 获取实例的方法共有。[ 提供返回实例对象的方法 getInstace() ]

    三、评判单例模式的标准

  6. 线程的安全性、

  7. 性能、
  8. 懒加载(lazy )

    四、 常用的单例模式

    1、 单例的饿汉模式 ```

public class Singleton { /*

  1. * 利用静态变量来记录Singleton的唯一实例
  2. * 直接初始化静态变量,这样就可以确保线程安全了
  3. */
  4. private static Singleton uniqueInstance = new Singleton();
  5. /*
  6. * 构造器私有化,只有Singleton类内才可以调用构造器
  7. */
  8. private Singleton() {
  9. }
  10. public static Singleton getInstance() {
  11. return uniqueInstance;
  12. }

}

  1. - 线程安全性:在加载的时候已经被实例化,所以只有这一次,线程安全的。JVM ClassLoader
  2. - 懒加载:没有延迟加载,好长时间不使用,影响性能
  3. - 性能比较好
  4. 2 懒汉式

public class HoonSingleton { private static HoonSingleton instance=null; private HoonSingleton(){ } public static HoonSingleton getInstance(){ if(null==instance) instance=new HoonSingleton(); return instance; } }

  1. - 线程安全性:不能保证实例对象的唯一性(不安全)<br />
  2. ![](http://zhangwenjun-1258908231.cos.ap-nanjing.myqcloud.com/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/20200130114018504.png)
  3. - 懒加载:延迟加载
  4. 3、懒汉的双重加锁机制 DCL Double-Check-Locking

package cn.njauit;

public class Singleton { /*

  1. * 利用静态变量来记录Singleton的唯一实例
  2. * volatile 关键字确保:当uniqueInstance变量被初始化成Singleton实例时,
  3. * 多个线程正确地处理uniqueInstance变量(保证了有序性,解决了编译重排重排和运行重排问题)
  4. *
  5. */
  6. private volatile static Singleton uniqueInstance;
  7. /*
  8. * 构造器私有化,只有Singleton类内才可以调用构造器
  9. */
  10. private Singleton() {
  11. }
  12. /*
  13. *
  14. * 检查实例,如果不存在,就进入同步区域
  15. */
  16. public static Singleton getInstance() {
  17. if (uniqueInstance == null) {
  18. synchronized (Singleton.class) { //进入同步区域
  19. if (uniqueInstance == null) { //在检查一次,如果为null,则创建
  20. uniqueInstance = new Singleton();
  21. }
  22. }
  23. }
  24. return uniqueInstance;
  25. }

}

  1. - 性能比较好
  2. - 懒加载:是
  3. - 线程的安全性:安全
  4. 4、静态内部类(Holder 型)
  5. > 静态内部类延迟加载

package cn.njauit;

public class Singleton {

  1. //声明类的时候,成员变量中不声明实例变量,而放到内部静态类中
  2. private static class LazyHolder {
  3. private static final Singleton INSTANCE = new Singleton();
  4. }
  5. private Singleton (){}
  6. //懒加载
  7. public static final Singleton getInstance() {
  8. return LazyHolder.INSTANCE;
  9. }

}

  1. 5.1、枚举单例示例

public enum EnumSingleton { INSTANCE;//INSTANCE 就是 EnumSingleton 的常量,只能初始化一次,天生为单例 public EnumSingleton getInstance(){ return INSTANCE; } }

  1. 5.2 完整的枚举单例

package cn.njauit;

public class EnumSingletonDemo { private EnumSingletonDemo() { }

  1. //匿名内部静态枚举类具有延迟加载性质
  2. private enum EnumHolder {
  3. /**
  4. * 创建一个枚举对象,该对象天生为单例
  5. */
  6. INSTANCE;
  7. private EnumSingletonDemo instance;
  8. EnumHolder() {
  9. instance = new EnumSingletonDemo();
  10. }
  11. }
  12. //懒加载 //对外暴露一个获取Instance的静态方法
  13. public static EnumSingletonDemo getInstance() {
  14. return EnumHolder.INSTANCE.instance;
  15. }

}

```