单例模式学习笔记
2023-06-13 09:12:12 时间
单例模式学习笔记
概念:
系统中只有一个该类的一个对象实例
使用场景
redis
连接对象Spring IOC
容器中的默认beanSpringBoot
中的controller
、service
、dao
层通过Autowire
的依赖注入对象默认都是单例的。
懒汉模式
用途:懒加载、延时加载,延迟创建对象
实现方式:
- 私有化构造函数,不能随便new对象。
- 对外提供一个获取对象实例的方法。
详细代码
package com.example.test.single;
/**
* @author 晓果冻
* @version 1.0
* @date 2021/10/21 21:47
*/
public class SingletonLazy {
public static SingletonLazy instance;
/**
* 构造函数私有化,外界不能通过new创建该对象
*/
private SingletonLazy() {
}
/**
* 对外只提供一个创建实例的方法,多线程下不安全
*
* @return
*/
public static SingletonLazy getInstance() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
/**
* 通过synchronized枷锁保证多线程下的单例
* 但synchronized开销大,又是在方法级别上控制的
*
* @return
*/
public static synchronized SingletonLazy getInstance02() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
/**
* 这是否安全,instance = new SingletonLazy(); 并不是原子性操作
* 1、分配空间给对象
* 2、在空间内创建对象
* 3、将对象赋值给引用instance
*
* 假如线程 1-》3-》2顺序,会把值写会主内存,其他线程就会读取到instance最新的值,但是这个是不完全的对象
* (指令重排)
* @return
*/
public static SingletonLazy getInstance03() {
if (instance == null) {
//假设此时同时有A、B线程满足到达这里
synchronized (SingletonLazy.class) {
//加锁 控制只有一个线程占有此锁
if (instance == null) {
//涉及双重锁检查,如果现在堆中分配了空间,堆是线程共享的,所以其他线程都可以读到此空间内容
instance = new SingletonLazy();
}
}
}
return instance;
}
/**
* volatile是Java提供的关键字,它具有可见性和有序性,
* 指令重排序是JVM对语句执行的优化,只要语句间没有依赖,那JVM就有权对语句进行优化
* 禁止了指令重排
*/
private static volatile SingletonLazy volatileInstance01;
public static SingletonLazy getInstance04() {
//第一重检查
if (volatileInstance01 == null) {
// A、B ,锁定
synchronized (SingletonLazy.class) {
//第二重检查
if (volatileInstance01 == null) {
volatileInstance01 = new SingletonLazy();
}
}
}
return volatileInstance01;
}
}
饿汉模式
用途:因为饿,所以急切需要对象。提前创建对象
实现方式:
- 私有化构造函数,不能随便new对象。
- 对外提供一个获取对象实例的方法。
详细代码
package com.example.test.single;
/**
* @author cgd
* @date 2021/10/27 17:54
*/
public class SingletonHungry {
private static SingletonHungry instance = new SingletonHungry();
private SingletonHungry() {
}
public static SingletonHungry getInstance() {
return instance;
}
}
俩种方式对比
- 饿汉
- 优点:实现简单,没有多线程问题
- 缺点:不论是否使用,实例对象一直占用这段空间
- 懒汉
- 优点:按需使用,不浪费空间
- 缺点:实现复杂
- 如何选择:
- 对象不大,且创建不复杂,直接使用饿汉
- 其他情况使用懒汉
JDK
源码中的单例设计模式
示例代码仓库地址:https://gitee.com/cgd0526/demo
相关文章
- Spring Cloud 学习笔记(2 / 3)
- ASP.Net MVC开发基础学习笔记:一、走向MVC模式
- pytorch学习笔记七:torchvision.datasets.ImageFolder使用详解
- SpringMVC学习笔记
- 前端学习笔记
- web前端学习/工作笔记(十二)
- 【Pytorch学习笔记十二】循环神经网络(RNN)详细介绍(常用网络结构及原理)
- Cloudsim学习笔记——基本知识
- ES6 学习笔记(五)基本类型Boolean
- 学习笔记 | Android开发常用的几种模式
- 一文带你快速搭建框架(最全MyBatis笔记)
- Vue学习笔记(一)
- MySql基础-笔记2 -数据库创建、删除、选择等操作
- Linux源码学习笔记day6 模式转换是什么鬼?
- 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程
- 【论文笔记】A Sequence-to-Sequence Approach to Dialogue State Tracking
- MongoDB入门到进阶笔记:05-MongoDB索引查询与建立 createIndex getIndexes dropIndex 性能优化
- mysql学习笔记 第九天详解数据库
- Java学习笔记之四java进制转化详解编程语言
- Oracle学习记录:把握未来(Oracle学习笔记)
- 千峰Redis学习笔记(千峰redis笔记)
- JSON学习笔记
- AJax学习笔记二(onreadystatechange的作用)
- jQuery学习笔记(4)--Jquery中获取table中某列值的具体思路
- MongoDB学习笔记(三)在MVC模式下通过Jqgrid表格操作MongoDB数据
- Javascript学习笔记之对象篇(三):hasOwnProperty