当前位置: 首页 > news >正文

Java 中单例模式的常见实现方式

目录

一、什么是单例模式?

二、单例模式有什么作用?

三、常见的创建单例模式的方式

 1、饿汉式创建

2、懒汉式创建

3、DCL(Double Checked Lock)双检锁方式创建

3.1、synchronized 同步锁的基本使用

3.2、使用 DCL 中存在的疑问

        3.2.1、为什么不直接在静态方法上加 synchronized 关键字,直接上锁?

        3.2.2、为什么 synchronized 代码块中锁的是当前类对象,为什么不是 this ?


一、什么是单例模式?

        单例模式是一种创建型设计模式,它确保类只有一个实例,并提供全局访问点让外部代码可以访问该实例。

        在 Java 中,可以使用单例模式来实现一些全局性的操作,例如配置文件管理线程池管理数据库连接池管理等等。这些操作只需要在程序运行的时候创建一次实例,在整个程序生命周期内都可以通过该实例来访问这些全局资源。

二、单例模式有什么作用?

  1. 避免对不需要的对象进行重复的创建,从而节省系统资源。
  2. 提供一个全局可访问的唯一实例,方便对该实例进行管理和操作。
  3. 确保类只有一个实例存在,避免出现因为实例化多个对象而产生的各种问题,例如状态不一致、资源争抢等问题。
  4. 提供一种常用的解决方案,能够帮助程序员更好地组织和管理代码。

三、常见的创建单例模式的方式

 1、饿汉式创建

//线程安全
class HungrySingleton {//在一开始就创建完成对象private static HungrySingleton hungrySingleton = new HungrySingleton();//私有的构造方法,别的类中无法对该类进行创建private HungrySingleton() {}//使用静态方法,直接使用 类名. 的形式就可以调用该方法public static HungrySingleton getInstance() {return HungrySingleton.hungrySingleton;}
}

2、懒汉式创建

//线程不安全
class LazySingleton {//一开始命名了对象,但是并没有创建private static LazySingleton lazySingleton;private LazySingleton() {}//当存在多个线程调用该方法,就会导致创建的对象不一致。public static LazySingleton getInstance() {if (lazySingleton == null) {lazySingleton = new LazySingleton();}return lazySingleton;}
}

3、DCL(Double Checked Lock)双检锁方式创建

//基于懒汉式进行双检锁,线程安全
class DCLSingleton {//需要使用 volatile 关键字防止指令重排,因为对象的创建过程中存在着半初始化过程private static volatile DCLSingleton dclSingleton;private DCLSingleton() {}public static DCLSingleton getInstance() {//第一步:先进行判断对象是否为空,避免了所有线程访问直接就去竞争锁if (dclSingleton == null) {//第二步:对一个线程加锁,其他线程等待synchronized (DCLSingleton.class) {/*第三步:会继续判断对象是否创建,是为了避免当时有多个线程到达第二步的等待阶段,一旦对象创建完成,锁被释放,此时其他的线程就会获取锁,如果不判断就会创建新的对象*/if (dclSingleton == null) {dclSingleton = new DCLSingleton();}}}return dclSingleton;}
}

3.1、synchronized 同步锁的基本使用

/*** synchronized的不同使用地点的不同含义。* 要保证锁的对象是不会变化的。*/public class SynchronizedTest {//1.使用在静态方法上,此时锁的对象为当前类对象 => SynchronizedTest.classpublic static synchronized void Test(){}//2.使用在非静态方法上,此时锁的对象是当前类的对象 => thispublic synchronized void Test1(){Object o=new Object();//3.synchronized代码块,此时锁的对象是括号中的对象synchronized(o){}}
}

3.2、使用 DCL 中存在的疑问

        3.2.1、为什么不直接在静态方法上加 synchronized 关键字,直接上锁?
/* 在方法上直接使用 synchronized 关键字,是对整个方法都加锁了,就算对象已经创建,也会使得每个线程来访问都要进行同步操作,降低效率public static synchronized DCLSingleton getInstance(){if(dclSingleton==null){dclSingleton=new DCLSingleton();}return dclSingleton;}*/
        3.2.2、为什么 synchronized 代码块中锁的是当前类对象,为什么不是 this ?

        在Java中,synchronized关键字可以用于不同的锁定对象。如果我们在DCL中使用当前类的对象 this 作为锁定对象,那么每个线程都会尝试获取该锁,这样就无法实现同步。因为每个线程都会创建自己的对象实例,而不是共享同一个实例。

        通过在synchronized代码块中使用当前类对象作为锁定对象,可以保证在多线程环境下只有一个线程能够进入该代码块,从而实现对象的单例模式。这是因为类对象是唯一的,所有线程都可以通过该对象来同步访问代码块。

相关文章:

  • 计算机网络 第五章(运输层)【下】
  • js 字符串功能转换解析
  • ubuntu v2ray
  • JDBC常见的几种连接池使用(C3PO、Druid、HikariCP 、DBCP)
  • 代码随想录第三十六天(一刷C语言)|背包问题理论基础分割等和子集
  • 【稳定检索|投稿优惠】2024年区域经济与经济转型国际学术会议(IACREET 2024)
  • 2023年度佳作:AIGC、AGI、GhatGPT 与人工智能大模型的创新与前景展望
  • Elasticsearch的批量bulk 提交 写入的方式会有顺序问题吗?
  • 设计模式(三)-结构型模式(3)-装饰模式
  • 2023.12.20力扣每日一题
  • 苏宁易购商品详情API:电商实时数据
  • Linux开发工具——vim篇
  • Ubuntu系统的基础操作和使用
  • 华大基因基因检测产品PMseq®,助力应对微生物耐药带来的挑战
  • 计算机基础:网络基础
  • CSS中外联样式表代表的含义
  • Django 博客开发教程 8 - 博客文章详情页
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • java8 Stream Pipelines 浅析
  • Javascript 原型链
  • JSDuck 与 AngularJS 融合技巧
  • laravel5.5 视图共享数据
  • Median of Two Sorted Arrays
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 翻译--Thinking in React
  • 关于for循环的简单归纳
  • 两列自适应布局方案整理
  • 前端之Sass/Scss实战笔记
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 实现菜单下拉伸展折叠效果demo
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 在weex里面使用chart图表
  • 怎么将电脑中的声音录制成WAV格式
  • 国内开源镜像站点
  • 数据可视化之下发图实践
  • ​iOS实时查看App运行日志
  • #stm32驱动外设模块总结w5500模块
  • (2015)JS ES6 必知的十个 特性
  • (C语言)球球大作战
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (javascript)再说document.body.scrollTop的使用问题
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (一)WLAN定义和基本架构转
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .Net Web项目创建比较不错的参考文章
  • .NET 中 GetProcess 相关方法的性能
  • .net下简单快捷的数值高低位切换
  • :not(:first-child)和:not(:last-child)的用法
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [ 渗透工具篇 ] 一篇文章让你掌握神奇的shuize -- 信息收集自动化工具
  • [20170713] 无法访问SQL Server
  • [Avalon] Avalon中的Conditional Formatting.