Java—单例模式

什么是单例模式?

单例模式是一种软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。在单例模式中,类自身负责创建自己的唯一实例,并且保证在整个应用程序中只能访问到这个实例。

实现步骤:

  1. 私有化构造方法;
    1. 私有化构造方法,防止通过new 创建对象。
  2. 提供静态方法入口;
    1. 对外提供一个公开的静态方法,获取类的唯一实例入口。
    2. 定义成静态是为了能通过类访问,因为私有化构造方法,外界无法获取实例对象,所以不能通过实例对象访问。
  3. 定义静态变量;
    1. 定义一个私有的单例类的静态变量,在类加载的时候,初始化静态变量。
    2. 为什么是私有的:
      1. 保护单例类的安全性,禁止外界对单例类的改变。
      2. 保证单例类的唯一性,不能修改唯一实例对象。
    3. 为什么是静态的:
      1. 因为入口方法是静态的,静态方法中只能访问静态成员变量。
      2. 也符合静态的特征,在类加载时,初始化静态变量,且只执行一次。

实现(饿汉式):

        1. 提前创建好单例实例对象。

        2. 调用时,直接返回创建好的单例实例对象。

/**
*	单例模式:
* 		饿汉式
*/
public class Singleton {private String name;// 唯一实例对象, 静态变量private  static Singleton singleton = new Singleton();// 私有化构造方法; 外界就不能创建当前类对象了。private Singleton(){}// 提供一个外界可以获取唯一实例的入口public static Singleton getInstance(){return singleton;}public String getName(){return name;}public void setName(String name){this.name = name;}
}	

实现(懒汉式):

        1. 在用到时,才创建单例实例对象。

        2. 调用时,判断是否已经创建过单例实例对象,如果创建过直接返回,否则创建再返回。

/**
*     单例模式:
*          懒汉式
*/
public class Singleton {private String name;// 唯一实例对象,但是不初始化private static Singleton singleton;// 访问入口,获取单例实例对象的唯一入口。public static Singleton getInstance(){// 如果对象为空,说明时第一次访问,创建单例实例对象。if( singleton == null){singleton = new Singleton();}return singleton;}public String getName(){reutnr name;}public void setName(String name){this.name = name;}
}

多线程环境实现:

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;}protected Object readResolve() {return getInstance();}
}

在上述代码中,通过添加volatile关键字修饰instance变量,确保多线程环境下对该变量的可见性和有序性,避免了线程安全问题。

在静态方法getInstance()中,首先检查instance是否为null,如果为null才会进入同步块。在同步块内部再次判断instance是否为null,这是为了防止多个线程同时通过第一个判断,并同时进入同步块创建实例,从而导致多个实例的产生。

此外,还需要注意到readResolve()方法的存在。当单例类被序列化后再进行反序列化时,可能会生成新的实例,为了避免这种情况,可以添加readResolve()方法,并在方法内返回单例实例。这样可以确保反序列化后获得的对象仍然是同一个实例。

这是一个完整版的单例模式示例代码,通过双重检查锁定和防止反射攻击的处理,保证了单例类的线程安全性和唯一性。

饿汉式和懒汉式的区别:

饿汉式和懒汉式是两种常见的单例模式实现方式,它们的区别主要体现在初始化时机和线程安全性上。

  1. 饿汉式:

    • 在类加载的时候就创建了对象实例,无论是否使用都会创建。
    • 在类加载过程中就完成了实例化,因此不存在多线程并发的问题。
    • 可能会浪费一些资源,因为不管有没有使用到该实例,都会提前创建。
  2. 懒汉式:

    • 延迟实例化,只有在第一次使用时才会创建对象实例。
    • 在多线程环境下,需要考虑并发访问的线程安全问题。
    • 相比饿汉式,懒汉式在不使用时不会提前创建实例,节省了一些资源。

需要注意的是,在多线程环境下使用懒汉式时,需要进行额外的处理来保证线程安全性,以避免多个线程同时创建多个实例。常见的线程安全处理方式包括使用 synchronized 关键字、双重检查锁定等。

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

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

相关文章

IDEA通过tomcat运行注意事项

配置run--》edit configurations 以下的A B部分要保持一致 A和B的路径要保持一致

前端vue项目遇到的问题01——那些初级问题

前端vue项目遇到的问题01——那些初级问题 1. npm install 问题1.1 依赖冲突1.1.1 详细问题1.1.2 报错原因1.1.3 解决问题1.1.3.1 方式1——无视冲突1.1.3.1 方式2——更换依赖版本 1.2 nodejs版本问题1.3 node版本正确的情况(audit问题)(这个…

Java链表简介

在Java中使用链表作为一种数据结构,并将其与MySQL作为底层数据库进行集成,涉及几个关键方面,包括数据存储、数据操作的效率、以及如何在应用层和数据库层之间映射数据结构。下面是对这些方面的分析: ### Java中的链表数据结构 链…

HTML5新特性、JS【初识JS 、JS核心语法】--学习JavaEE的day47

day47 HTML5新特性 定义文档类型 在文件的开头总是会有一个标签 语言文档类型声明方式html4<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">html5<!DOCTYPE html> 新增语义化标签 理解&…

vite-plugin-vue-devtools插件

vite-plugin-vue-devtools插件旨在帮助开发者更快地理解并调试Vue应用。它通过提供全面的功能和直观的界面&#xff0c;以图形化的方式展示应用程序状态&#xff0c;使开发者能够更方便地查看和管理Vue应用的各个方面。此外&#xff0c;该插件还支持Vue3.0版本&#xff0c;并且…

【Go专家编程——内存管理——垃圾回收】

垃圾回收 所谓的垃圾就上不在需要的内存块&#xff0c;垃圾如果不清理&#xff0c;这些内存块就没有办法再次被分配使用。在不支持垃圾回收的编程语言中&#xff0c;这些垃圾内存就上泄露的内存。 1. 垃圾回收算法 常见的垃圾回收算法有3种 引用计数&#xff1a;对每个对象…

yolov10 快速使用及训练

参考: https://docs.ultralytics.com/models/yolov10/ ultralytics其实大多数系列都能加载使用: 官方: https://github.com/THU-MIG/yolov10.git 代码参考: https://colab.research.google.com/github/roboflow-ai/notebooks/blob/main/notebooks/train-yolov10-object-…

一篇文章讲透排序算法之希尔排序

希尔排序是对插入排序的优化&#xff0c;如果你不了解插入排序的话&#xff0c;可以先阅读这篇文章&#xff1a;插入排序 目录 1.插入排序的问题 2.希尔排序的思路 3.希尔排序的实现 4.希尔排序的优化 5.希尔排序的时间复杂度 1.插入排序的问题 如果用插入排序对一个逆序…

521源码-免费代码基础学习-PHP如何运用变量教程

更多网站源码学习教程&#xff0c;请点击&#x1f449;-521源码-&#x1f448;获取最新资源 为什么要学习PHP&#xff1f;“我可以用JavaScript来实现程序编写。”但JavaScript的能力是有限的&#xff0c;JavaScript通常运行在浏览器&#xff08;客户端&#xff09;&#xff0…

go语言中for的4种循环形式总结

和其他语言不一样&#xff0c;go语言中的循环语句只有for一种&#xff0c;但是go里面的for却有3种不同的循环形式&#xff0c;总结如下&#xff1a; 1. 无限循环 for { //这个就是一个“死循环”&#xff0c;注意必须要有 break条件&#xff0c;否则就真成死循环了 } 2. fo…

Redis 源码学习记录:集合 (set)

无序集合 Redis 源码版本&#xff1a;Redis-6.0.9&#xff0c;本篇文章无序集合的代码均在 intset.h / intset.c 文件中。 Redis 通常使用字典结构保存用户集合数据&#xff0c;字典键存储集合元素&#xff0c;字典值为空。如果一个集合全是整数&#xff0c;则使用字典国语浪费…

PostgreSQL入门教程

PostgreSQL是一种开源的关系型数据库管理系统&#xff0c;它具有高度的可靠性、可扩展性和性能。下面是一个简单的PostgreSQL入门教程&#xff0c;帮助你开始使用这个强大的数据库管理系统。 步骤1&#xff1a;安装PostgreSQL 首先&#xff0c;你需要下载并安装PostgreSQL。你…

2024年最全的信息安全、数据安全、网络安全标准分享(可下载)

以上是资料简介和目录&#xff0c;如需下载&#xff0c;请前往星球获取&#xff1a;https://t.zsxq.com/Gz1a0

【全网最全】2024电工杯数学建模A题成品论文+前三题完整解答matlab+py代码等(后续会更新成品论文)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片链接&#xff0c;那是获取资料的入口&#xff01; 【全网最全】2024电工杯数学建模A题成品论文前三题完整解答matlabpy代码等&#xff08;后续会更新成品论文&#xff09;「首先来看看目前已有的资料&am…

Python 点云平面分割【RANSAC算法】

点云平面分割 一、介绍1.1 概念1.2 算法思路1.3 参数设置二、代码示例三、结果示例其他参考链接:C++中实现点云平面分割 一、介绍 1.1 概念 点云平面分割:可以在点云数据中找到平面并计算平面模型系数,同时输出平面点云及非平面点云。 1.2 算法思路 实现思路: 首先,采用…

Sass是什么?有哪些优缺点?

目录 一、Sass是什么&#xff1f; 二、Sass的优缺点 三、Sass与SaaS 一、Sass是什么&#xff1f; Sass是世界上最成熟、最稳定、最强大的专业级CSS扩展语言。 Sass makes CSS fun again. Sass is an extension of CSS, adding nested rules, variables, mixins, selector in…

【C++高阶(一)】继承

目录 一、继承的概念 1.继承的基本概念 2.继承的定义和语法 3.继承基类成员访问方式的变化 ​编辑 4.总结 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 1.派生类中的默认构造函数 2.派生类中的拷贝构造函数 3.派生类中的移动构造函数…

英语学习笔记25——Mrs. Smith‘s kitchen

Mrs. Smith’s kitchen 史密斯太太的厨房 词汇 Vocabulary Mrs. 夫人【已婚】 复习&#xff1a;Mr. 先生 全名 / 姓    Mrs. 夫人 全名 / 丈夫的姓    Miss 小姐&#xff08;未婚&#xff09; 全名 / 姓    Ms. 女士 全名 / 姓 查看婚姻状况&#xff0c;可以观察…

springboot项目中图片上传之后需要重启工程才能看到图片?

需求背景 最近在做一个用户自定义上传头像的小需求&#xff0c;用户上传头像然后需要立马回显。 需求是很常见的、正当的需求。如果不使用到对象存储这类服务&#xff0c;我们把用户头像的图片文件仅存在本地就可以了。我们在开发的过程中为了工程管理方便通常下意识会将图片…

freertos串口DMA队列发送卡死

调试回调函数的时候&#xff0c;我在cube中删除了默认的DMA通道&#xff0c;又新增了另外一个通道&#xff0c;导致NVIC中&#xff0c;该通道的优先级为0&#xff0c;后来改成了5就正常了。