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

javaEE——单例模式

目录

  • 前言
  • 1.概念
  • 2. 实现
  • 3. 比较和改进
  • 总结

前言

本篇文章来介绍单例模式,并讲述在保证线程安全的前提下,单例模式的写法。

1.概念

单例模式是一种设计模式,可以说是写代码的一种模板,如果在一些固定的场景下按照设计模式进行写代码,写出来的代码一定不会很差。
设计模式有非常多种,这里就介绍单例模式这一种。
单例指的是单个实例,在一些场景中,我们希望一个类只能有唯一的实例,我们就可以使用单例模式这种设计模式。

2. 实现

下面介绍如何在Java中实现单例模式,单例模式有很多种实现方法,在这里我们就介绍两种最常用的:饿汉式和懒汉式。
饿汉式是先创建一个静态的实例,通过getInstance方法来获取这个唯一的实例,下面看例子:

//单例模式之饿汉式
class Singleton{//先创建一个静态的实例private static Singleton instance = new Singleton();public static Singleton getInstance(){return instance;}private Singleton(){//私有化构造方法}
}public class Demo23 {public static void main(String[] args) {Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println(s1 == s2); // true}
}

注意,要将构造方法私有化,来防止外部自行创建新的实例。
懒汉式则是在第一次调取getInstance方法时,才会创建实例,下面看示例:

//单例模式之懒汉式
class SingletonLazy {private static SingletonLazy instance;private SingletonLazy() {//私有化构造方法}public static SingletonLazy getInstance() {if (instance == null) {instance = new SingletonLazy();}return instance;}
}public class Demo24 {public static void main(String[] args) {SingletonLazy s1 = SingletonLazy.getInstance();SingletonLazy s2 = SingletonLazy.getInstance();System.out.println(s1 == s2); // true}
}

3. 比较和改进

如果我们在多线程条件下调用getInstance,不难发现,懒汉模式线程不安全,因为在多个线程调用getInstance时,可能会判定到好几次instance == null,这样会导致创建好几个不同的实例。在饿汉模式下,由于已经提前创建好实例,调用getInstance只会返回这个实例,所以线程安全。
下面对懒汉模式进行改进,保证其线程安全:

//单例模式之懒汉式
class SingletonLazy {private static volatile Object locker = new Object();private static SingletonLazy instance;private SingletonLazy() {//私有化构造方法}public static SingletonLazy getInstance() {if (instance == null) {synchronized (locker){if (instance == null) {instance = new SingletonLazy();}}}return instance;}
}

对实例化对象进行加锁,由于每次一个线程都要先加锁,操作过于繁琐,所以在外层再添加一个判断条件,判断instance是否被实例化,如果实例化则直接返回instance,不需要再进行加锁判断,在此之后,还要给locker加上volatile关键字,防止编译器优化,这里的编译器优化是“指令重排序”,而进行优化之后,多线程进行操作的时候会出现问题,导致instance还没有初始化就被返回,这是指令重排序而造成的线程安全问题。

总结

这篇文章简单介绍了线程安全模式下单例模式的写法,希望对大家有所帮助。

http://www.xdnf.cn/news/3860.html

相关文章:

  • FreeRTOS菜鸟入门(十)·消息队列
  • MySQL用户管理
  • 以下是在 Ubuntu 上的几款PDF 阅读器,涵盖轻量级、功能丰富和特色工具:
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]: [1]如何加载动态链接库, 并无缝支持原生底层开发?
  • iview 表单验证问题 Select 已经选择 还是弹验证提示
  • 【Java 并发编程】线程的基本使用(持续更新优化)
  • 【沐风老师】3DMAX按元素UV修改器插件教程
  • Ubuntu环境下使用uWSGI服务器【以flask应用部署为例】
  • 【2025软考高级架构师】——知识脑图总结
  • Spring AI聊天模型API:轻松构建智能聊天交互
  • 软考-软件设计师中级备考 12、软件工程
  • nginx 正反向代理和nginx正则
  • 数据分析之药物-基因-代谢物
  • RAGFlow 接入企业微信应用实现原理剖析与最佳实践
  • IP 协议
  • 性能优化实践:内存优化技巧
  • iview 老版本合并单元格
  • 基于Hive + Spark离线数仓大数据实战项目(视频+课件+代码+资料+笔记)
  • Linux环境部署iview-admin项目
  • gitblit安装教程,搭建一个属于自己的Git版本仓库
  • Python读取comsol仿真导出数据并绘图
  • 【操作系统】哲学家进餐问题
  • 【前缀和】和为 K 的连续子数组
  • 软件检测价格受多种因素影响,你了解多少?
  • 【SAP】FISL的应用
  • 2023华为od机试C卷【跳格子3】
  • 高维亚空间超频物质变压缩技术 第27次CCF-CSP计算机软件能力认证
  • 《应用开发突围指南:敏捷开发的实战精髓》
  • 2001-2021年各城市平均风速数据(可作工具变量)
  • INP指标