徒手撸设计模式-单例模式
2022-07-06 17:21 hikoukay 阅读(42) 评论(0) 编辑 收藏 举报概念
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
参考连接: https://www.runoob.com/design-pattern/singleton-pattern.html
代码案例
公共类
public final class StFlag { public StFlag() { } /** * 饿汉式 */ public static final String HUNDER="HUNDER"; /** * 双重检验锁 */ public static final String DCL="DCL"; /** * 懒汉式非安全 */ public static final String LAZYUNSAFE="LAZYUNSAFE"; /** * 懒汉式安全 */ public static final String LAZYSAFE="LAZYSAFE"; /** * 静态内部类 */ public static final String STATICINNER="STATICINNER"; }
五种单例模式
DCL
/** * double check locking 双重检验锁 */ @Slf4j public class SingletonDCL { //创建 SingleObject 的一个对象 private volatile static SingletonDCL instance ; //让构造函数为 private,这样该类就不会被实例化 private SingletonDCL(){} //获取唯一可用的对象 public static SingletonDCL getInstance(){ if (instance ==null){ synchronized (SingletonDCL.class){ if (instance ==null){ instance=new SingletonDCL(); } } } return instance; } public void showMessage(){ log.info("DCL say Hello World!=========="+instance.hashCode()); } }
饿汉式
/** * 饿汉式 */ @Slf4j public class SingletonHunger { //创建 SingleObject 的一个对象 private static SingletonHunger instance = new SingletonHunger(); //让构造函数为 private,这样该类就不会被实例化 private SingletonHunger(){} //获取唯一可用的对象 public static SingletonHunger getInstance(){ return instance; } public void showMessage(){ log.info("Hunger say Hello World!=========="+instance.hashCode()); } }
懒汉安全
/** * 懒汉安全 */ @Slf4j public class SingletonLazySafe { //创建 SingleObject 的一个对象 private static SingletonLazySafe instance ; //让构造函数为 private,这样该类就不会被实例化 private SingletonLazySafe(){} //获取唯一可用的对象 public static synchronized SingletonLazySafe getInstance(){ if (instance ==null){ instance=new SingletonLazySafe(); } return instance; } public void showMessage(){ log.info("Lazy Safe say Hello World!=========="+instance.hashCode()); } }
懒汉非安全
/** * 懒汉非安全 */ @Slf4j @Service("lazyUnSafe") public class SingletonLazyUnSafe { //创建 SingleObject 的一个对象 private static SingletonLazyUnSafe instance ; //让构造函数为 private,这样该类就不会被实例化 private SingletonLazyUnSafe(){} //获取唯一可用的对象 public static SingletonLazyUnSafe getInstance(){ if (instance ==null){ instance=new SingletonLazyUnSafe(); } return instance; } public void showMessage(){ log.info("Lazy UnSafe say Hello World!=========="+instance.hashCode()); } }
静态内部类
/** * 静态内部类 */ @Slf4j @Service("staticInner") public class SingletonStaticInner { private static class SingletonStaticInnerClass{ //创建 SingleObject 的一个对象 private static final SingletonStaticInner instance = new SingletonStaticInner(); } //让构造函数为 private,这样该类就不会被实例化 private SingletonStaticInner(){} //获取唯一可用的对象 public static SingletonStaticInner getInstance(){ return SingletonStaticInnerClass.instance; } public void showMessage(){ log.info("DCL say Hello World!=========="+SingletonStaticInnerClass.instance.hashCode()); } }
测试类
/** * 设计模式控制器 */ @RestController @RequestMapping("/designPattern") @Slf4j public class DesignController { @GetMapping("/singleton") public ResponseModel singleton(String singletonType) { if (StringUtils.isEmpty(singletonType)) { return new ResponseModel("请输入正确的单例模式类型", 500, null); } if (StFlag.DCL.equals(singletonType)) { SingletonDCL instance = SingletonDCL.getInstance(); instance.showMessage(); return new ResponseModel("双重检验锁单例创建成功", 200, instance.hashCode()); } else if (StFlag.HUNDER.equals(singletonType)) { SingletonHunger instance = SingletonHunger.getInstance(); instance.showMessage(); return new ResponseModel("饿汉式单例创建成功", 200, instance.hashCode()); } else if (StFlag.LAZYSAFE.equals(singletonType)) { SingletonLazySafe instance = SingletonLazySafe.getInstance(); instance.showMessage(); return new ResponseModel("懒汉式安全单例创建成功", 200, instance.hashCode()); } else if (StFlag.LAZYUNSAFE.equals(singletonType)) { SingletonLazyUnSafe instance = SingletonLazyUnSafe.getInstance(); instance.showMessage(); return new ResponseModel("懒汉式非安全单例创建成功", 200, instance.hashCode()); } else if (StFlag.STATICINNER.equals(singletonType)) { SingletonStaticInner instance = SingletonStaticInner.getInstance(); instance.showMessage(); return new ResponseModel("内部类单例成功", 200, instance.hashCode()); } return null; } }
测试案例
每个请求发两次比较hash值
饿汉式
双重检验锁
懒汉非安全
懒汉式安全
静态内部类
控制台日志
2022-06-16 02:01:18.638 INFO Hunger say Hello World!==========593888302 【http-nio-8081-exec-4】【SingletonHunger:21】 2022-06-16 02:01:29.767 INFO Hunger say Hello World!==========593888302 【http-nio-8081-exec-2】【SingletonHunger:21】 2022-06-16 02:02:13.813 INFO DCL say Hello World!==========682619383 【http-nio-8081-exec-1】【SingletonDCL:31】 2022-06-16 02:02:15.836 INFO DCL say Hello World!==========682619383 【http-nio-8081-exec-9】【SingletonDCL:31】 2022-06-16 02:02:47.905 INFO Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-10】【SingletonLazyUnSafe:24】 2022-06-16 02:02:50.264 INFO Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-8】【SingletonLazyUnSafe:24】 2022-06-16 02:03:11.053 INFO Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-7】【SingletonLazySafe:24】 2022-06-16 02:03:15.359 INFO Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-6】【SingletonLazySafe:24】 2022-06-16 02:03:37.376 INFO DCL say Hello World!==========150313621 【http-nio-8081-exec-5】【SingletonStaticInner:26】 2022-06-16 02:03:39.190 INFO DCL say Hello World!==========150313621 【http-nio-8081-exec-3】【SingletonStaticInner:26】