【设计模式】单例模式(创建型)⭐⭐⭐

1.概念

1.1 什么是单例模式

单例模式属于创建型模式,一个单例类在任何情况下都只存在一个实例
构造方法必须是私有的、由自己创建一个静态变量存储实例,对外提供一
个静态公有方法获取实例。

1.2 优点与缺点

优点:是内存中只有一个实例,减少了开销,尤其是频繁创建和销毁实例的情况下,可以避免对资源的多重占用。
缺点:没有抽象层,难以扩展,与单一职责原则冲突(单例模式由于其全局访问的特性,往往会使得类的使用变得非常广泛,这会导致类的职责膨胀,变得越来越难以维护。)。

2.实现方式

2.1 懒汉式

懒加载 (lazy loading):使用的时候再创建对象。

2.1.1 懒汉式(线程不安全)

在第一次调用获取实例的方法时才创建实例。由于没有同步措施,因此线程不安全。

public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

2.1.2 懒汉式(线程安全)

在懒汉式的基础上,通过同步代码块或方法来确保线程安全,但会降低性能。

public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

2.2 饿汉式

类加载时就创建好实例,避免了线程同步问题,但可能会导致资源浪费。

public class Singleton {private static Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}

2.3 双重检查锁定(Double-Checked Locking)

结合懒汉式和线程安全的特点,在获取实例时进行双重检查,以提高性能。

public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

volatile关键字的作用是确保instance变量的可见性和防止指令重排序。

2.4 静态内部类

利用Java的类加载机制来实现懒加载和线程安全。

public class Singleton {private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}

在这个示例中,SingletonHolder是一个静态内部类,它包含了一个静态的Singleton实例。SingletonHolder类只有在getInstance()方法被调用时才会被加载,这保证了Singleton实例的延迟加载。同时,由于类的加载过程是线程安全的,所以这种方式也保证了单例的线程安全。

2.5 枚举

使用枚举来实现单例模式,这是最简单的实现方式,并且天生线程安全,防止多次实例化。

public enum Singleton {INSTANCE1,INSTANCE2;public void someMethod() {// 功能处理System.out.println("执行一些功能处理");}
}
public class Main {public static void main(String[] args) {// 调用第一个枚举实例的方法Singleton.INSTANCE1.someMethod();// 调用第二个枚举实例的方法Singleton.INSTANCE2.someMethod();}
}

枚举天生线程安全的原因在于Java枚举的设计和实现:
枚举实例的创建时机:枚举的实例是在类加载时创建的,这个过程是由Java虚拟机(JVM)在加载枚举类时自动完成的。JVM确保在任何线程可以访问枚举的实例之前,这些实例已经被创建并初始化完毕
Java内存模型(JMM):Java内存模型确保了所有线程可以看到枚举实例的创建和初始化状态。这意味着在任何线程可以访问枚举的实例之前,这些实例的状态对于所有线程都是可见的
同步机制:在枚举实例的创建过程中,JVM内部会使用同步机制来确保实例的创建是原子性的,也就是说,在创建枚举实例的过程中,不会有其他线程干扰。
不可变性:枚举实例一旦被创建,就不能被修改或重新赋值。这意味着多个线程可以安全地访问枚举实例,而不会出现竞态条件或数据不一致的问题。
由于这些原因,枚举天生就是线程安全的,不需要开发者手动处理同步问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/21709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【力扣】不同的子序列

一、题目描述 给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 7 取模。 示例 1: 输入:s "rabbbit", t "rabbit"输出: 3 解释: 如下所示, 有 3 种…

【十年java搬砖路】Jumpserver docker版安装及配置Ldap登陆认证

Jumpserver docker 安装启动教程 拉取镜像 docker pull JumpServer启动进行前确保有Redis 和Mysql 创建jumperServer数据库 在MYSQL上执行 创建数据库 登陆MYSQL mysql -u root -p 创建Jumperserveri库 create database jumpserver default charset utf8mb4;可以为jumperSe…

ubuntu 22.04配置静态ip

ubuntu 22.04配置静态ip vim /etc/netplan/01-network-manager-all.yaml# Let NetworkManager manage all devices on this system network:renderer: NetworkManagerethernets:enp4s0f1:addresses:- 192.168.1.18/24dhcp4: falseroutes:- to: defaultvia: 192.168.1.1nameser…

「动态规划」买卖股票的最佳时机

力扣原题链接,点击跳转。 给定一个整数数组prices,prices[i]表示股票在第i天的价格。你最多完成2笔交易。你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。设计一个算法计算最大利润。 我们用动态规划的思想来解决…

【软件开发】Java学习路线

本路径视频教程均来自尚硅谷B站视频,Java学习课程我已经收藏在一个文件夹下,B站文件夹同时会收藏其他Java视频,感谢关注。指路:https://www.bilibili.com/medialist/detail/ml3113981545 2024Java学习路线(快速版&…

揭秘YAML:Python中的PyYAML应用

🍀 前言 博客地址: CSDN:https://blog.csdn.net/powerbiubiu 👋 简介 本章节介绍YAML文件格式的操作,通过Python的第三方库 PyYaml 来实现文件操作,在 Pyhon 代码中无论读取还是写入,都是使用…

React ahooks库和React Query库使用场景分析

文章目录 前言一、在一个前台项目中,如区块链项目,需大量轮询接口,这时候哪个好二、ahooks一般可以用在什么项目上三、推荐react-query一些常用的hook四、推荐ahooks一些常用的hook总结 前言 ahooks和react-query都是好用的react库&#xff…

【机器学习】逻辑回归:原理、应用与实践

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 逻辑回归:原理、应用与实践引言1. 逻辑回归基础1.1 基本概念1.2 Sig…

视频汇聚EasyCVR安防系统对接公安部GA/T 1400视图库布控、告警、订阅流程描述

随着信息技术的飞速发展,视频监控在公共安全领域的应用越来越广泛,对于视频监控系统的要求也日益严格。为了满足公安系统对视频图像信息应用的高标准需求,视频汇聚平台EasyCVR视频监控系统全面支持GA/T 1400标准协议,为公安部门提…

Scala学习笔记8: 包

目录 第八章 包1- 包2- 包的作用域3- 串联式包语句4- 包对象5- 引入end 第八章 包 在Scala中, 包(Package) 用于组织和管理代码, 类似与 Java 中的包 ; 包可以包含类、对象、特质等Scala代码, 并通过层次结构来组织代码 ; 可以使用 package 关键字来定义包, 并使用 . 来表示…

基于JSP的母婴用品网站系统

你好呀,我是计算机学长猫哥!如果有需求可以文末加我。 开发语言:Java 数据库:MySQL 技术:JSP技术 工具:IDEA/Eclipse、Navicat、Maven 系统展示 首页 管理员功能界面 用户功能界面 前台首页功能界面 …

Java开发-面试题-0003-List、Set 和 Map的区别

Java开发-面试题-0003-List、Set 和 Map的区别 更多内容欢迎关注我(持续更新中,欢迎Star✨) Github:CodeZeng1998/Java-Developer-Work-Note 技术公众号:CodeZeng1998(纯纯技术文) 生活公众…

一个小时搞定JAVA面向对象(4)——继承

文章目录 继承继承中,成员变量和成员方法的访问特点当子类和父类的成员变量不重名:当子类和父类的成员变量重名: 成员方法方法的重写方法重写注意事项 final、Supre和this关键字final关键字final关键字修饰变量final关键字修饰方法 super的使用方法this的使用方法继承的特点 继…

BioPorto胰高血糖素样肽-1抗体(GLP-1)

丹麦BioPorto Diadnostics公司致力于提供世界领先的GLP-1抗体。基于结合GLP-1位点的不同,他们筛选出了不同的抗GLP-1抗体。有的抗体可以同时结合GLP-1的活性形式和非活性形式,有的专门结合生物活性形式的GLP-1。在开发和检测GLP-1相关治疗的过程中&#…

deepin 社区月报 | 2024年5月,deepin V23 RC 正式发布,校园联盟走进海外!

deepin(深度)社区5月总览 2024年5月,有1052位小伙伴加入了deepin(深度)社区大家庭,目前共有论坛伙伴154962位; 在5月,deepin V23 正式发布了RC版本,在本次发布的RC版本…

最新版点微同城源码34.7+全套插件+小程序前后端

带全套插件 自己耐心点配置一下插件 可以H5可以小程序 一款专属的同城服务平台对于企业和个人而言,无疑是拓展业务、提升服务品质的重要一环。点微同城源码搭配全套插件,以及完善的小程序前后端,将为您的业务发展提供强大支持 源码免费下载…

黑马程序员——Spring框架——day04——SpringMVC基础

目录: SpringMVC简介 背景SpringMVC概述技术体系定位快速入门 目的需求步骤代码实操测试工具 PostMan简介PostMan安装PostMan使用知识点总结请求与参数处理 请求路径 环境准备问题分析解决方式请求方式 环境准备技术分析参数 基本数据类型POJO嵌套POJO数组集合&…

【面试题-015】Redis的线程模型是什么 为什么速度快

redis面试题 Redis的线程模型是什么 为什么速度快? Redis是一个开源的、高性能的键值对(key-value)数据库。它之所以速度快,主要得益于以下几个方面的设计: 单线程模型: Redis的操作是单线程的&#xff…

【JAVA |总结】JAVASE基础大总结(含思维导图)

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 🎈丠丠64-CSDN博客🎈 ✨✨ 帅哥美女们,我们共同加油!一起…

Excel的VLOOKUP函数的用法

由于工作需要,最近用Excel的时候比较多,遇到一个需求,刚好需要用到VLOOKUP函数,结果由于对参数的理解不清晰,导致折腾了很久,都没达到想要的效果。所以,这里特此就遇到的坑做一个记录&#xff0…