设计模式学习笔记--单例模式
来源:互联网 发布:淘宝最迟发货时间 编辑:程序博客网 时间:2024/05/29 10:41
三、单例模式
单例模式(Singleton Pattern)是Java中最简单的设计模式之一,涉及到一个单一的类,负责创建自己的对象且确保唯一,并提供对外调用方式。
- 单例类只能有一个实例对象
- 单例类必须自己创建自己的唯一实例对象
- 单例类必须给所有其他对象提供这一实例。
介绍
单例类提供一个可供全局访问的唯一的实例对象,用于全局频繁操作的单一对象,有助于节省系统资源。单例模式构造函数私有。
应用场景举例:1、多线程文件操作时候,操作文件的对象需要单一,以保证操作安全(当然需要配合线程同步)。2、唯一序列号的产生。3、web网站全局计数器。
- 优点:1、内存里只有一个实例,减少内存开销,尤其是频繁的创建与销毁实例。2、避免对资源的多重占用(如操作文件)。
- 缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不应关心外部实例化的问题。
**注意事项:**getInstance()方法中需要使用同步锁synchronized(Singleton.class)
防止多线程同时进入造成instance多次实例化。
实现
创建一个SingleObject类,私有化其构造函数并创建一个静态实例,对外提供一个静态方法,来获取它的静态实例。SingletonPatternDemo,来演示获取SingleObject的单例对象。
创建Singleton类
SingleObject.java
public class SingleObject { //创建一个SingleObject的对象 private static SingleObject instance = new SingleObject(); //私有化构造函数 private SingleObject(){} //对外提供对象实例 public static SingleObject getInstance(){ return instance; } //单例类的其他方法 public void showMsg(){ System.out.println("Hello World!"); }}
获单一实例
SingletonPatternDemo.java
public class SinglePatternDemo { public static void main(String[] args){ //单例模式对象实例的获取,不能用new的方式,因为其构造函数私有化了,只能通过它提供的实例获取方法获取实例对象。 SingleObject object = SingleObject.getInstance(); //调用对象的其他方法 object.showMsg(); }}
- 输出结果
Hello World!
单例模式的集中实现方式
单例模式有多种实现模式
懒汉式、线程不安全
lazy loading、非线程安全、简单易实现;由于非线程安全,严格意义上不算单例模式。但是在不要求线程安全的情况下,简便易用。
public class Singleton { private static Singleton instance; private Singleton(){} //对外提供对象单例 public static Singleton getInstance(){ if (instance == null){ instance = new Singleton(); } return instance; }}
以下都是线程安全的单例模式,效率不同
懒汉式、线程安全
线程安全形式的lazy loading,支持多线程,简单,但是效率低。
- 优点:第一次调用才初始化,避免内存浪费。
- 缺点:必须加
synchronized
锁才能保证单例,而影响效率。
public class Singleton { private static Singleton instance; private Singleton(){} //同步锁方法,对外提供单例对象 public static synchronized Singleton getInstance(){ if (instance == null){ instance = new Singleton(); } return instance; }}
饿汉式
饿汉式简单常用,线程安全,但是易产生垃圾。
- 优点:无加锁,效率高。
- 缺点:静态初始化,浪费内存。
饿汉式通过
classloader
机制来避免多线程同步问题。但并没有达到lazy loading的记载效果。
public class Singleton { private static Singleton instance = new Singleton(); private Singleton(){} //类似懒汉式,但是静态初始化对象实例了。 public static Singleton getInstance(){ ruturn instance; }}
双检锁/双重校验锁(DCL,即double-checked locking)
采用双锁机制,多线程下高效执行,但是实现难度大。lazy loading、线程安全、复杂。且在JDK1.5后采用。
public class Singleton { private volatile static Singleton singleton; private Singleton(){} // public static Singleton getInstance(){ if (singleton == null){ //同步代码块 synchronized (Singleton.class){ //再次判断是否非空,避免多线程风险。 if (singleton == null){ singleton = new Singleton(); } } } return singleton; }}
登记式/静态内部类
lazy loading、线程安全、难度一般。该形式可以达到如上双检锁一样的功效,实现更方便。仅适用于静态域延迟初始化,而双检锁方式可在实例域需要延迟初始化时使用。
登记式同样利用了classloader机制,不同于饿汉式:1、饿汉式的instance随Singleton
类初始化,没有lazy loading(lazy可避免浪费内存);而登记式的instance不一定随Singleton初始化,因为Singleton Holder类没有被主动使用。所以登记式比饿汉式更合理。
public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton(){} //登记式对外单例 public static final Singleton getInstance(){ return SingletonHolder.INSTANCE; }}
枚举
不lazy loading、线程安全、简单。这是实现单例模式最佳的方式,但开发中使用者较少。简洁、自动序列化、绝对防止多次实例化。JDK1.5以后采用。
public enum Singleton { INSTANCE; public void whateverMethod(){ }}
Note:一般不建议使用第1、2种懒汉方式,建议使用第3中饿汉式。只有明确实现lazy loading效果时才使用第5种登记式。涉及到反序列化对象时候,尝试第6种枚举式。若有特殊要求,可以考虑第4中双检锁方式。
- 设计模式学习笔记:单例模式
- 设计模式学习笔记-单例模式
- 设计模式学习笔记--单例模式
- 设计模式学习笔记-单例模式
- 设计模式学习笔记-单例模式
- 设计模式学习笔记--单例模式
- 设计模式--单例模式学习笔记
- 设计模式学习笔记----单例模式
- 【设计模式学习笔记】单例模式
- 学习设计模式笔记--单例模式
- 学习笔记07-设计模式之单例设计模式
- JavaSE学习笔记--单例设计模式
- 学习笔记--单例设计模式
- 设计模式之单例学习笔记
- HeadFirst 设计模式学习笔记5--单例模式
- HeadFirst 设计模式学习笔记5--单例模式
- C#设计模式学习笔记-单例模式
- java 设计模式 学习笔记(16) 单例模式
- jsp的常见动作
- 润乾报表图形报表部署在Linux下出现乱码解决办法
- SpringMVC+Spring+MyBatis 项目pom.xml 文件模板
- 单、复选框美化
- css 中多个class选择器的详解
- 设计模式学习笔记--单例模式
- PLSQL调试存储过程无法进入单步调试
- CoolFormat 源代码格式化工具使用手册
- 记事本(纯界面)
- 【微信小程序】小程序入门之创建目录和tabBar配置
- TIOBE开发语言排行榜
- single task Activity不能使用startActivityForResult解释
- 扫描二维码和签到打卡应用程序
- iphone如何查看SIM联系人