单例模式:控制实例创建数目

简介: 单例模式的本质是在于控制实例创建数目

场景分析

多个客户端通过new 多个配置对象的实例来获取配置内容,而配置对象的获取的内容都是一样的,只需要一个实例即可。多个配置对象严重浪费系统内部资源。

image.png
定义及本质

定义:保证一个类只有一个实例,并提供一个访问它的全局访部点。
本质:控制实例创建数目。
功能:保证类在运行期间只会被创建一个类的实例。
范围:一个虚拟机的范围,如果一台机器有多个虚拟机,每个虚拟机都会有一个类的实例,这个类就是多例;
命名:getInstance()
结构示意图:

image.png

解决方案
1 懒汉式
一个私有化构造器、一个静态方法、一个静态属性
延迟加载思想:一开始不需要加载资源或数据,等使用的时候再加载,节约资源。
缓存思想:当某资源或数据频繁被使用,将其缓存到内存中,节省时间,典型的以空间换时间的方案。
2 饿汉式:利用static特性
static 变量在类装载的时候进行初始化;
多个实例的static 变量会共享同一块内存区域;
3 静态内部类实现单例,延迟加载(类级内部类)
Lazy initialization holder class模式,这个模式综合使用了Java的类级内部类和多线程缺省同步锁的知识,很巧妙的同时实现了延迟加载和线程安全。
类级内部类可以让类装载时不去初始化对象,只要不使用到这个类级内部类,就不会创建对象实例。

(1)Java的类级内部类
什么是类级内部类?

类级内部类指的是:有static修饰的成员式内部类。如果没有static修饰的成员式内部类被称为对象级内部类。

类级内部类相当于其外部类的static成分,它的对象与外部类对象间不存在依赖关系,因此可直接创建。而对象级内部类的实例,是绑定在外部对象实例中的。
类级内部类中,可以定义静态的方法,在静态方法中只能够引用外部类中的静态成员方法或者成员变量。
类级内部类相当于其外部类的成员,只有在第一次被使用的时候才会被装载
(2)多线程缺省同步锁
为了解决并发问题,主要是通过使用synchronized来加互斥锁进行同步控制。但是在某些情况中,JVM已经隐含地执行了同步,这些情况下就不用自己再来进行同步控制了。
由静态初始化器(在静态字段上或 static{} 块中的初始化器)初始化数据时;
访问 final 字段时;
在创建线程之前创建对象时;
线程可以看见它将要处理的对象时;

枚举类实现单例
(1)枚举类型的基本思想
通过公有的静态final域为每个枚举常量导出实例的类。枚举是单例的泛型化,本质上是单元素的枚举。
(2)枚举实现单例的好处
自由序列化(枚举本身已实现Serializable接口);
线程安全(通过静态final域实现,JVM初始化时线程安全);
简洁易用;

UML类图
image.png

调用时序图
image.png

优缺点
(1)时间和空间
懒汉式是典型的时间换空间:每次获取实例时先要判断是否需创建实例。
饿汉式是典型的空间换时间:类装载时就会创建类实例;
(2)线程安全
懒汉式是非线程安全的,饿汉式是线程安全的(类装载时没有并发);
懒汉式安全实现机制:
第一种:加上synchronized,每次进入getInstance方法都需要同步,降低了访问速度;
第二种:双重检查加锁

相关文章
|
5月前
|
运维 Serverless 数据处理
函数计算产品使用问题之配置了预留实例,如果请求超时实例是否会退出
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
4月前
|
运维 Java Serverless
函数计算产品使用问题之事件函数单实例的并发度默认是多少
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
126 6
函数计算产品使用问题之事件函数单实例的并发度默认是多少
|
4月前
|
运维 Serverless API
函数计算产品使用问题之如何配置单实例的并发数
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
4月前
|
存储 监控 Serverless
函数计算产品使用问题之预留实例的闲置模式设置在什么地方进行
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
5月前
|
运维 Serverless API
函数计算产品使用问题之访问某个函数,不是预留实例,如何不让它销毁掉
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
设计模式 缓存 安全
Java代理模式:如何优雅地控制对象访问?
Java代理模式:如何优雅地控制对象访问?
240 1
|
Java C#
C#的构造器以及内存状态
C#的构造器以及内存状态
98 0
|
存储 算法 Java
运行时数据区中包含哪些区域?哪些线程共享?哪些线程独享?
运行时数据区中包含哪些区域?哪些线程共享?哪些线程独享?【⭐⭐⭐⭐⭐】 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。 JDK 1.8 和之前的版本略有不同,下面会介绍到。
329 0
运行时数据区中包含哪些区域?哪些线程共享?哪些线程独享?
|
设计模式 安全 Java
Java设计模式——单例模式——全局唯一 节省资源
本文目录 1. 场景 2. 简单实现 3. 简单实现的bug 4. 多线程环境保持单例 5. 效率不咋地 6. 提高多线程下效率
214 0