设计模式之单例模式
2021/9/29 23:10:41
本文主要是介绍设计模式之单例模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
单例模式
定义
在整个程序中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象的方法。
饿汉式(静态常量)
构造器私有化,无法通过new创建对象,在类的内部完成对象的创建,对外提供一个静态方法,返回该对象的实例。
/** * 饿汉式静态常量的实现方式 */ public class HungryStaticConstant { //构造器私有化,无法通过new创建对象, private HungryStaticConstant(){} private final static HungryStaticConstant hungryStaticConstant = new HungryStaticConstant(); //对外提供一个静态方法,返回该对象的实例 public static HungryStaticConstant getInstance(){ return hungryStaticConstant; } }
优点: 写法简单,类装载的时候完成了实例化,避免了线程同步的问题。
缺点: 没有完成懒加载的效果,如果没有用到这个实例会造成资源浪费。
饿汉式(静态代码块)
与静态常量类似
/** * 饿汉式(静态代码块实现) */ public class HungryStaticCodeBlock { //构造器私有化,无法通过new创建对象, private HungryStaticCodeBlock(){} private static HungryStaticCodeBlock hungryStaticCodeBlock; //静态代码块,返回实例对象 static{ hungryStaticCodeBlock = new HungryStaticCodeBlock(); } //对外的静态方法,返回对象的实例 public static HungryStaticCodeBlock getInstance(){ return hungryStaticCodeBlock; } }
优点缺点同饿汉式(静态常量)
懒汉式(线程不安全)
/** * 线程不安全的懒汉式实现 */ public class LazyNonSafeThread { private static LazyNonSafeThread lazyNonSafeThread; //构造函数私有化 private LazyNonSafeThread(){} //提供一个静态方法,当使用该方法时才创建实例 public static LazyNonSafeThread lazyNonSafeThread(){ if(lazyNonSafeThread == null){ //没创建时,创建实例 lazyNonSafeThread = new LazyNonSafeThread(); } return lazyNonSafeThread; } }
优点: 起到了懒加载的效果,但是只能在单线程下使用。
缺点: 如果多线程的情况下,多个线程都进入到了if判断的情况中就会产生多个实例,就不是单例模式了。
懒汉式(线程安全)
/** * 懒汉式线程安全的实现方式 */ public class LazySafeThread { private static LazySafeThread lazySafeThread; //构造函数私有化 private LazySafeThread(){} //提供一个静态方法,当使用该方法时才创建实例 public static synchronized LazySafeThread lazySafeThread(){ if(lazySafeThread == null){ //没创建时,创建实例 lazySafeThread = new LazySafeThread(); } return lazySafeThread; } }
问题: 效率太低,获取线程实例的时候每次都要进行同步。
双重检查实现单例模式
/** * 单例模式双重检查实现方式 */ public class DoubleCheck { //增加volatile关键字 private static volatile DoubleCheck doubleCheck; private DoubleCheck(){} public static DoubleCheck doubleCheck(){ //第一层检查 if(doubleCheck == null){ synchronized (DoubleCheck.class){ //第二层检查 if(doubleCheck == null){ doubleCheck = new DoubleCheck(); } } } return doubleCheck; } }
解决了线程安全问题,同时也解决了懒加载问题。
实际开发中推荐使用这种单例设计模式。
静态内部类
/** * 静态内部类实现单例模式 */ public class StaticInnerClass { private StaticInnerClass(){} //类装载的时候静态内部类不会装载 private static class InnerClass{ private final static StaticInnerClass staticInnerClass = new StaticInnerClass(); } public static StaticInnerClass getInstance(){ return InnerClass.staticInnerClass; } }
当调用getInstance时才会装载内部类,装载时是线程安全的,所以此方法也是线程安全的并且兼顾懒加载的特性。
此外还可以同步借助枚举来实现单例模式,不仅能避免多线程的同步问题,而且还能通过反序列化重新创建对象,也是《EFFECTIVE JAVA》的作者Josh Bloch提倡的方式
在Java中Runtime就是经典的单例模式:
使用场景: 需要频繁创建和销毁对象,重量级对象(创建对象耗时过多或消耗资源过多),经常用到的对象、工具类对象等。
这篇关于设计模式之单例模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-06小米11i印度快充版ROM合集:极致体验,超越期待
- 2024-10-06【ROM下载】小米11i 5G 印度版系统, 疾速跃迁,定义新速度
- 2024-10-06【ROM下载】小米 11 青春活力版,青春无极限,活力全开
- 2024-10-05小米13T Pro系统合集:性能与摄影的极致融合,值得你升级的系统ROM
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求