单例模式-Java实现-非延迟加载、延迟加载
目录
第一种:非延迟加载
第二种:同步延迟加载
第三种:双重检测同步延迟加载
第四种:使用内部类实现延迟加载(推荐)
第五种:枚举
单例模式:确保在任何时候,该类只有唯一 一个实例。
第一种:非延迟加载
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}
第二种:同步延迟加载
public class Singleton {private static Singleton instance = null;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
多线程情况下,每一次获取,都需要获取同步锁,导致执行效率低下。
第三种:双重检测同步延迟加载
public class Singleton {private volatile static Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) { // 1if (instance == null) { // 2instance = new Singleton(); // 3 (旧版本:还没初始化完成,就已经对其它线程可见了)}}}return instance;}
}
只需在第一次创建实例时才同步,一旦创建成功,以后获取实例时就不需要获取同步锁了。
- 线程 1 进入 getInstance() 方法。
- 由于 instance 为 null,线程 1 在 //1 处进入 synchronized 块。
- 线程 1 前进到 //3 处,但在构造函数执行之前,使 instance 成为非 null。
- 线程 1 被线程 2 预占。
- 线程 2 检查 instance 是否为 null。因为 instance 不为 null,线程 2 将 instance 引用返回一个构造完整但部分初始化了的 Singleton 对象。
- 线程 2 被线程 1 预占。
- 线程 1 通过运行 Singleton 对象的构造函数并将引用返回给它,来完成对该对象的初始化。
mem = allocate(); //为单例对象分配内存空间instance = mem; //instance 引用指向内存,此时 instance 不为 null,但还未初始化construct(instance); //调用构造函数进行初始化
可以看出旧版本中, instance =new Singleton() 不具有操作的原子性。
Java 1.5 以前对实例变量是直接在主存中读写的,也就是以上 3 行伪代码的每一步操作,对于其它线程都是可见的。
Java 1.5 以后,JMM发生了根本性的改变,以上 3 行伪代码都在线程的工作空间中完成的,在没有向主存写入变量之前,其它线程对这个过程都是不可见的。volatile 关键字在这里有两个作用,一是禁止指令序列的“乱序执行”,让重排后的指令之间的依赖变得有序,必须让变量初始化完成后,才能够执行依赖于它的其它指令;二是执行完 3 行伪代码后,立即把变量 instance 写入到主存,该变量才对其它线程可见。
第四种:使用内部类实现延迟加载(推荐)
public class Singleton {private Singleton() {//实例的初始化}static class SingletonHolder {static Singleton instance = new Singleton();}public static Singleton getInstance() {return SingletonHolder.instance;}
}
静态内部类SingletonHolder只会被初始化一次,因为在被类加载器加载后,对SingletonHolder的Class对象只会进行一次初始化。
第五种:枚举
public enum Singleton { INSTANCE; public void fun() { }
}
单例模式-Java实现-非延迟加载、延迟加载相关推荐
- Java异步非阻塞编程的几种方式
简介: Java异步非阻塞编程的几种方式 一. 从一个同步的Http调用说起 一个很简单的业务逻辑,其他后端服务提供了一个接口,我们需要通过接口调用,获取到响应的数据. 逆地理接口:通过经纬度获取这个 ...
- 单例模式——java设计模式
单例模式 目录: 一.何为单例 二.使用Java EE实现单例模式 三.使用场景 一.何为单例 确保一个类只有一个实例,并且提供了实例的一个全局访问点 1.1 单例模式类图 ...
- java非负整数怎么设_使用JAVA将非负十进制整数n转换成b进制,递归方法与非递归方法...
使用JAVA将非负十进制整数n转换成b进制,递归方法与非递归方法 使用JAVA将非负十进制整数n转换成b进制,递归方法与非递归方法 一.题目要求 将非负十进制整数n转换成b进制.(其中b=2~16) ...
- 用Java实现非阻塞通信
用ServerSocket和Socket来编写服务器程序和客户程序,是Java网络编程的最基本的方式.这些服务器程序或客户程序在运行过程中常常会阻塞.例如当一个线程执行ServerSocket的acc ...
- 拉马努金的整数拆分全排列JAVA实现非递归
拉马努金的整数拆分全排列JAVA实现非递归 点这里: 递归方式 结果是:组合成100的可能性共有:190569292种!! 不做详细说明了,需要看文字描述的,点上面链接跳转递归方式,查看详细说明 来, ...
- Java运行非Web的Springboot项目(测试类或启动主类两种方法)
Java运行非Web的Springboot项目(测试类或启动主类两种方法) 前言 一.创建打开一个Springboot项目 二.运行项目 1.Test测试类运行 2.启动主类运行 三.持续运行不停止( ...
- java i 非原子性_java i++ 非原子操作
java i++ 非原子操作 i++ 不是原子操作, 也就是说, 它不是单独一条指令, 而是 3 条指令: 1, 从内存中把 i 的值取出来放到 CPU 的寄存器中 2,CPU 寄存器的值 + 1 3 ...
- java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】
第1章 Mybatis 延迟加载策略 1.1 何为延迟加载? 1.2 实现需求 1.3 使用 assocation 实现延迟加载 1.3.1 账户的持久层 DAO 接口 1.3.2 账户的持久层映射文 ...
- java 四种实现延迟加载的方法
1. 延迟初始化 2. 虚拟代理(virtual proxy) 原文地址: http://www.oodesign.com/proxy-pattern.html Intent The intent ...
最新文章
- 基于局部表面特征在杂乱场景中的三维物体识别
- python中四种进制的输出_Python基础语法和进制
- 用WebCollector爬取新浪微博数据
- 乐鑫代理-启明云端分享ESP32系列教程之二:Linux搭建esp-idf环境
- python操作redis中的list
- 使用Azure DevOps Pipeline实现.Net Core程序的CD
- 网络 传输层 | UDP协议与TCP协议详解(三次握手及四次挥手、滑动窗口、拥塞控制)
- join为什么每个字符都分割了 js_为什么 webpack4 默认支持 ES6 语法的压缩?
- ADS2022学习笔记(二)
- Class和class? 类对象和类的对象? 一篇文章让你摸到头脑
- Android Base64编码解码
- qcloud_cos 的安装问题
- python随机森林变量重要性_python机器学习之随机森林(七)
- 计算机专业大学排名(全168所学校)
- Excel提取18位/15位身份证出生日期②
- 腾讯技术团队整理,年度好文轻松彻底入门 Flutter,秒变大前端
- python行业中性_用python进行金融市场文本数据的情感计算
- 轻松学习JavaScript十一:JavaScript基本类型(包含类型转换)和引用类型
- 计算机对会计有什么好处,会计专业转行干过设计工作,这些宝贵经验和感悟,对你有用(三)...
- VintaSoft Twain.NET SDK,实现扫描文档
热门文章
- 嵌入式linux加载引导内核和根文件系统的方法
- JavaSE基础笔记
- QT次线程连接数据库
- Silverlight 4.0 Accordion 解决ScrollViewer 的问题
- Computer Systems A Programmer's Perspective(深入理解计算机系统)第一章读书笔记
- 实验吧web-易-what a fuck!这是什么鬼东西?
- Ubuntu14.04server 安装 fping
- 表单单选多选项清除默认样式小技巧
- 限制EditText只能输入小数点后两位
- 获取aplicationContext对象,从而获取任何注入的对象