设计模式 -- 单例模式

发布时间:2022-03-01 12:02:31 作者:yexindonglai@163.com 阅读(961)

单例模式的特点

    1、保证在jvm 中只有一个实例;
    2、应用场景:servlet 、springioc(默认单例)、连接池、线程池、枚举、常量;
    3、优点: 节省内存,重复使用,方便管理
    4、缺点:有线程安全问题;

 

单例模式的分类

        1、懒汉式:将单例对象设为静态属性并加上final修饰符,初始化单例类时就立即创建对象实例,天生线程安全;调用率高
        2、饿汉式:将单例对象设为静态属性并加上final修饰符,初始化单例类时不会立即创建对象实例,而是在使用的时候才创建实例,使用懒加载功能;此方式是线程不安全的
        3、内部静态类方式:新建一个内部类,将单例对象设为静态属性并加上final修饰符放在内部类里面,真正需要使用的时候才会创建对象实例,
        4、枚举式:使用简单,调用率高,因为枚举本身就是单例的,从jvm上就保证了单例,可以避免序列化和反射破坏单例,缺点是没有懒加载功能;枚举一般都是用来保存常量使用的;
        5、双重检测锁方式:懒加载方式,只在创建实例时才上锁,获取对象时不上锁;所以使用时只会锁一次;但是此方法会有重排序问题,已不建议使用;
 

 

 防止反射破坏单例,可以看我的另外一篇文章  https://blog.csdn.net/qq_27184497/article/details/115225855?spm=1001.2014.3001.5501

 

示例代码

1、饿汉式

  1. package com.designPatterm.single;
  2. /**
  3. * 单例模式--饿汉式
  4. * 线程安全,效率高
  5. */
  6. public class SingletonModelEHan {
  7. private static final SingletonModelEHan obj = new SingletonModelEHan();
  8. // 私有构造方法,防止创建多个实例
  9. private SingletonModelEHan(){
  10. // 防止反射破坏单例
  11. if(null != obj) throw new RuntimeException("单例模式不允许创建多实例");
  12. }
  13. // 获取实例
  14. public static SingletonModelEHan getInstance(){
  15. return obj;
  16. }
  17. public static void main(String[] args) {
  18. SingletonModelEHan instance = SingletonModelEHan.getInstance();
  19. }
  20. }

 

2、懒汉式

  1. package com.designPatterm.single;
  2. /**
  3. * 单例模式--懒汉式
  4. *
  5. * 线程安全,效率低
  6. *
  7. */
  8. public class SingletonModelLanHan {
  9. private static SingletonModelLanHan obj = null;
  10. // 私有构造方法,防止创建多个实例
  11. private SingletonModelLanHan(){
  12. // 防止反射破坏单例
  13. if(null != obj) throw new RuntimeException("单例模式不允许创建多实例");
  14. }
  15. // 获取实例,加锁实现线程安全
  16. public static synchronized SingletonModelLanHan getInstance(){
  17. if(null == obj){
  18. obj = new SingletonModelLanHan();
  19. }
  20. return obj;
  21. }
  22. public static void main(String[] args) {
  23. SingletonModelEHan instance = SingletonModelEHan.getInstance();
  24. }
  25. }

 

3、枚举式

  1. package com.designPatterm.single;
  2. /**
  3. * 单例模式--枚举式
  4. *
  5. */
  6. public class SingletonModelEnum {
  7. static enum Single{
  8. INSTANCE();
  9. private SingletonModelEnum obj;
  10. Single(){
  11. this.obj = new SingletonModelEnum();
  12. }
  13. public SingletonModelEnum getInstance(){
  14. return this.obj;
  15. }
  16. }
  17. // 私有构造方法,防止创建实例
  18. private SingletonModelEnum(){
  19. System.out.println("初始化了");
  20. }
  21. // 获取实例
  22. public static SingletonModelEnum getInstance(){
  23. return SingletonModelEnum.Single.INSTANCE.getInstance();
  24. }
  25. public static void main(String[] args) {
  26. SingletonModelEnum instance = SingletonModelEnum.getInstance();
  27. }
  28. }

 

4、内部静态类模式

  1. package com.designPatterm.single;
  2. /**
  3. * 单例模式--内部静态类模式
  4. *
  5. */
  6. public class SingletonModelInnerStatic {
  7. static class Single{
  8. // 内部类实现了延迟加载功能,调用 getInstance() 方法时才会创建实例,
  9. private static SingletonModelInnerStatic obj = new SingletonModelInnerStatic();
  10. }
  11. // 私有构造方法,防止创建多个实例
  12. private SingletonModelInnerStatic(){
  13. System.out.println("初始化了");
  14. }
  15. // 获取实例
  16. public static SingletonModelInnerStatic getInstance(){
  17. return Single.obj;
  18. }
  19. public static void main(String[] args) {
  20. SingletonModelInnerStatic instance = SingletonModelInnerStatic.getInstance();
  21. }
  22. }

 

5、双重检索模式

  1. package com.designPatterm.single;
  2. /**
  3. * 单例模式--双重检索模式
  4. * 不建议使用,此方法会有重排序问题
  5. */
  6. public class SingletonModelDoubleLock {
  7. private static SingletonModelDoubleLock obj = null;
  8. // 私有构造方法,防止创建多个实例
  9. private SingletonModelDoubleLock(){
  10. // 防止反射破坏单例
  11. if(null != obj) throw new RuntimeException("单例模式不允许创建多实例");
  12. }
  13. // 获取实例
  14. public static SingletonModelDoubleLock getInstance(){
  15. if(null == obj){
  16. synchronized (SingletonModelDoubleLock.class){
  17. if(null == obj){
  18. obj = new SingletonModelDoubleLock();
  19. }
  20. }
  21. }
  22. return obj;
  23. }
  24. public static void main(String[] args) {
  25. SingletonModelDoubleLock instance = SingletonModelDoubleLock.getInstance();
  26. }
  27. }

 

关键字设计模式