【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

🍎个人博客:个人主页

🏆个人专栏:JAVA

⛳️  功不唐捐,玉汝于成


目录

前言

正文

懒汉式(Lazy Initialization):

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

结语

我的其他博客


前言

在软件设计中,单例设计模式是一种重要的设计思想,它确保了一个类只有一个实例,并提供了一个全局访问点。在多线程环境下,实现线程安全的单例模式是必要的,以确保在并发操作中不会破坏单例的规则。

正文

单例设计模式是一种创建型设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。

在Java中实现线程安全的单例模式有多种方式,其中两种常见的方式是懒汉式和饿汉式。

  1. 懒汉式(Lazy Initialization):

    在懒汉式中,实例的创建是在第一次使用时进行的,以延迟初始化。

    public class LazySingleton {private static LazySingleton instance;private LazySingleton() {// 私有构造方法,防止外部直接实例化}public static synchronized LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
    }
    

    上述代码中,getInstance 方法使用了 synchronized 关键字,确保了多线程环境下的线程安全。但是,这样的实现会导致性能问题,因为每次调用 getInstance 时都要进行同步。

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

双重检查锁定是在懒汉式的基础上进行改进,通过双重检查减小了同步块的范围,提高了性能。

public class DoubleCheckedLockingSingleton {private static volatile DoubleCheckedLockingSingleton instance;private DoubleCheckedLockingSingleton() {// 私有构造方法,防止外部直接实例化}public static DoubleCheckedLockingSingleton getInstance() {if (instance == null) {synchronized (DoubleCheckedLockingSingleton.class) {if (instance == null) {instance = new DoubleCheckedLockingSingleton();}}}return instance;}
}

 在上述代码中,使用了 volatile 关键字来保证 instance 的可见性,并且使用了双重检查来确保只在第一次调用 getInstance 时才进行同步。

这两种方式都是线程安全的单例模式实现,开发者可以根据具体的需求选择适合自己项目的方式。近年来,也推荐使用静态内部类方式实现单例,以及利用枚举类型实现单例,它们都是更为简洁和安全的实现方式。 

结语

在Java中,线程安全的单例模式有多种实现方式,懒汉式和双重检查锁定是其中的两种常见方式。选择适合自己项目的方式时,需要考虑性能、延迟初始化、代码简洁性等因素。近年来,也出现了更为简洁和安全的实现方式,如使用静态内部类或者枚举类型。无论选择哪种方式,理解单例模式的设计原理对于编写健壮、高效的代码至关重要。希望通过学习单例模式,你能够更好地应用它,提高代码的可维护性和性能。

我的其他博客

【JAVA】线程的run()和start()有什么区别?-CSDN博客

【日常聊聊】程序员必备的面试技巧:如何在面试战场上脱颖而出-CSDN博客

【JAVA】Java8开始ConcurrentHashMap,为什么舍弃分段锁-CSDN博客

【JAVA】怎么确保一个集合不能被修改-CSDN博客

【Web开发】会话管理与无 Cookie 环境下的实现策略-CSDN博客

【Mybatis】Mybatis如何防止sql注入-CSDN博客

【软件工程】航行敏捷之路:深度解析Scrum框架的精髓-CSDN博客

【Spring】理解IoC与AOP:构建灵活而模块化的软件架构-CSDN博客

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

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

相关文章

antd时间选择器,设置显示中文

需求 在实现react,里面引入antd时间选择器,默认显示为英文 思路 入口处使用ConfigProvider全局化配置,设置 locale 属性为中文来实现。官方文档介绍全局化配置 ConfigProvider - Ant Design 代码 import React from react; import { Prov…

SpringBoot原理(@Conditional)—三种自动配置方法、步骤详解

简介:我们一直在说基于SpringBoot开发简单、快捷,但是总是不太清楚为什么会有这样的便利,对于开发人员来说我们不仅要知其然,还要知其所以然,这篇文章就是说明SpringBoot的底层原理,让读者对SpringBoot底层…

Emoji表情大全

等等... 推荐一下几个网站,去复制就可以啦! Emoji 表情大全All Emoji Symbols Are Collected Here, And Now Emoji Can Display On IOS, Android, OSX, And Windows Systems. Just The Symbol ✂ And 📋 To App, SMS, Facebook, Twitter An…

一卡通水控电控开发踩过的坑

最近在做一个项目,是对接一卡通设备的。我一开始只拿到设备和3个文档开局。不知道从哪下手。一步一步踩坑过来。踩了很多没有必要的坑,写出来给有用的人吧。 读卡器怎么用? 有个读卡器,一开始什么软件也不提供。我都不知道是干嘛…

基于JavaWeb+BS架构+SpringBoot+Vue+Hadoop的物品租赁系统的设计与实现

基于JavaWebBS架构SpringBootVueHadoop的物品租赁系统的设计与实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 目  录 I 1绪 论 1 1.1开发背景 1 1.2开发目的与意义 1 1.2.1开发目…

Rabbit R1是一款AI驱动的小工具,可以代替你使用应用程序

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

CES 2024丨引领变革,美格智能为智能终端带来生成式AI能力

作为电子行业的“风向标”,CES 2024(国际消费电子展)于1月9日至12日在美国拉斯维加斯举办。本届展会可谓是AI的盛宴,芯片、AI PC、智能家居、汽车科技、消费电子等领域与AI相关的前沿成果接连发布,引领人工智能领域的科…

MySQL 按日期流水号 条码 分布式流水号

有这样一个场景,有多台终端,要获取唯一的流水号,流水号格式是 日期0001形式,使用MySQL的存储过程全局锁实现这个需求。 以下是代码示例。 注:所有的终端连接到MySQL服务器获取流水号,如果获取到的是 “-1”…

.NET 反射的介绍和简单应用

什么是反射? 反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型,这些信息在设计时是未知的,这种能力类似于后期绑定。反射还支持的更高级的行为,能在运行时动态创建新类型&#xff0…

Ubuntu 20.04 Intel RealSense D435i 相机标定教程

下载编译code_utils mkdir -p ~/imu_catkin_ws/src cd ~/imu_catkin_ws/src catkin_init_workspace source ~/imu_catkin_ws/devel/setup.bash git clone https://github.com/gaowenliang/code_utils.git cd .. catkin_make报错:sumpixel_test.cpp:2:10: fatal err…

Spring Boot中加@Async和不加@Async有什么区别?设置核心线程数、设置最大线程数、设置队列容量是什么意思?直接在yml中配置线程池

在 Spring 中,Async 注解用于将方法标记为异步执行的方法。当使用 Async 注解时,该方法将在单独的线程中执行,而不会阻塞当前线程。这使得方法可以在后台执行,而不会影响主线程的执行。 在您提供的代码示例中,a1() 和…

纯html通过XMLHttpRequest访问java后端接口并将返回结果输出到控制台【建议收藏】

我们需要准备几个部分: 1、后端接口【servlettomcat】 2、前端页面代码 3、js发起请求部分 后端接口: WebServlet("/h1") public class HController extends HttpServlet {Overrideprotected void service(HttpServletRequest req, HttpS…