Java 设计模式--单例模式
来源:互联网 发布:运筹学与控制论 知乎 编辑:程序博客网 时间:2024/06/03 22:04
在 《Head First 设计模式》 中这么定义单例模式:
单件模式确保一个类只有一个实例,并提供一个全局访问点。
单件模式特点:
- 单例类只能有一个实例,只允许该类自己管理一个实例,同时避免其他类再自行产生实例,要想取得单件实例,通过单件类是唯一的途径。
- 有一个全局访问点,当你需要实例时,向类查询,它就返回单件实例。
类图
1. 其中这个 uniqueInstance 类变量持有唯一的单件实例。
2. getInstance 方法是静态的,这意味着它是一个类方法,所以可以在代码的任何位置使用 Singleton.getInstance() 访问它,并返回单件实例。
懒汉式单例
package com.example.administrator.myprofile;/** * 文 件 名: Singleton * 创 建 人: Bradley * 创建日期: 2017/10/13 21:59 * 修改时间: * 修改备注: */public class Singleton { /** * 利用一个静态变量来记录 Singleton 类的唯一实例 */ private static Singleton uniqueInstance; /** *将构造器设为私有的,只有 Singleton 内才能调用构造器 */ private Singleton(){}; /** * 用 getInstance 来实例化这个对象,并将这个对象返回 * @return Singleton */ public static Singleton getInstance(){ if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; }}
懒汉式是典型的时间换空间,就是每次获取实例都会进行判断,看时候需要创建实例,浪费判断时间。请注意,如果我们不需要这个实例,它就永远不会产生。这就是 “延迟实例化” (lazy instantiaze) 。
饿汉式单例
package com.example.administrator.myprofile;/** * 文 件 名: Singleton * 创 建 人: Bradley * 创建日期: 2017/10/13 21:59 * 修改时间: * 修改备注: */public class Singleton { /** * 在静态初始化器中创建单件,这段代码保证了线程安全 */ private static Singleton uniqueInstance = new Singleton(); /** *将构造器设为私有的,只有 Singleton 内才能调用构造器 */ private Singleton(){}; /** * 用 getInstance 来实例化这个对象,并将这个对象返回 * @return Singleton */ public static Singleton getInstance(){ return uniqueInstance; //已经有了实例,直接返回 }}
利用这个做法,我们依赖 JVM 在加载这个类时马上创建此唯一的单件实例。JVM 保证在任何线程访问 uniqueInstance 静态变量之前,一定先创建实例。
饿汉式是典型的控件换时间,当类装载的时候就创建类的实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断,节省了运行时间。
双重检查加锁
所谓“双重检查加锁”机制,指的是:并不是每次进入 getInstance 方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块,这是第一重检查,进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。
“双重检查加锁”机制的实现会使用关键字 volatile,它的意思是:被 volatile 修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。
package com.example.administrator.myprofile;/** * 文 件 名: Singleton * 创 建 人: Bradley * 创建日期: 2017/10/13 21:59 * 修改时间: * 修改备注: */public class Singleton { private volatile static Singleton uniqueInstance ; /** *将构造器设为私有的,只有 Singleton 内才能调用构造器 */ private Singleton(){}; /** * 第一步:检查实例,如果不存在,就进入同步区块 * 第二步:进入同步区块后,再检查一次,如果仍是 null ,才创建实例 * @return Singleton */ public static Singleton getInstance(){ if (uniqueInstance == null) { //只有第一次才彻底执行这里的代码 synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; //已经有了实例,直接返回 }}
完
- java 设计模式,单例设计模式
- java设计模式-单例设计模式
- java设计模式-单例设计模式
- Java设计模式 单例设计模式
- Java设计模式------单例设计模式
- java设计模式----->单例设计模式
- java设计模式:单例设计模式
- java设计模式-----单例设计模式
- Java设计模式----单例设计模式
- java设计模式-单例设计模式
- java设计模式:单例设计模式
- java 设计模式-单例设计模式
- Java设计模式--单例设计模式
- java设计模式---单例设计模式
- Java设计模式-单例设计模式
- JAVA设计模式:单例设计模式
- java-单例设计模式
- Java设计|单例模式
- 深刻理解Python中的元类(metaclass)
- PL/SQL之六 记录
- 10-13 第三日总结
- Date Mining References
- 数据结构之数组
- Java 设计模式--单例模式
- 标准C语言第三天
- c++造车
- 个人随笔
- DateTimeModel.cs
- 数据结构之栈
- Python中的random模块
- 关于整数输入的正序和倒序输出
- Kubernetes之“暂停”容器