关于Java中单例模式(饿汉模式和懒汉模式)的简析

article/2025/9/22 2:27:42

目录

一.什么是单例模式

二.饿汉模式和懒汉模式

饿汉模式

代码

懒汉模式

代码

关于多线程安全的问题

如何解决懒汉模式多线程安全问题

双if判断


一.什么是单例模式

简单来说,就是我们在程序中通过代码进行限制,在该程序中

只能创建一个对象

二.饿汉模式和懒汉模式

因为只能创建一个对象,所以对于我们而言就有两种方式

第一种方式

饿汉模式

让程序自动类中创建唯一的对象

在类外不能被创建

代码

class Student{//此处在类的内部一开始就自己创建了唯一的Student对象public static Student st = new Student();//提供private构造方法,让其在类外不能被调用private Student(){}//提供getInstance方法,以便获取唯一的Student对象public static Student getInstance(){return st;}
}
public class Main {public static void main(String[] args) {//此处的st2,和st3都指向唯一的st对象,还是只存在唯一一个对象Student st2 = Student.getInstance();Student st3 = Student.getInstance();}
}

第二种方式

懒汉模式

就是程序在自己内部不创建唯一对象

而是我们需要的时候再在类外面new那个唯一的对象

这种方式就叫做懒汉模式

代码

class Teacher{//将te指向空,等到get的时候再进行实例化,这里是没有指向任何对象private static Teacher te = null;//避免通过new的方式创建其他实例,只能通过get方式获取唯一实例private Teacher(){}//通过get创建唯一对象public static Teacher getInstance(){if(te == null){te  = new Teacher();}return te;}
}
public class demo1 {public static void main(String[] args) {//调用才创建对象Teacher te1 = Teacher.getInstance();}
}

关于多线程安全的问题

其实我们大体上就要记住一点

多线程同时修改同一份变量大概率就会发生线程安全的问题

所以在上述代码中

我们的饿汉模式在多线程的情况下

他不管调用几次都只是在返回已经创建好的那个唯一对象

只是相当于获取

并没有进行任何修改操作

但是在懒汉模式的多线程下

我们是进行了判断,然后创建的唯一对象,创建这个操作就是对数据进行了修改

那么多个线程同时对一个数据进行修改,那么就会发生多线程安全的问题

所以

饿汉模式没有多线程安全问题

懒汉模式多线程安全问题

如何解决懒汉模式多线程安全问题

加锁

加锁

还是(* * *)加锁

我们最优先想到的就是直接在get方法那里加上synchronized

class Teacher{private static Teacher te = null;private Teacher(){}
//直接加上一把锁public static synchronized Teacher getInstance(){if(te == null){te  = new Teacher();}return te;}
}

但是这样是会有问题的

因为此处的操作并不是原子性,那么如果是多线程进行操作,可能会出现下面的情况

 也就是说,我们可能会同时返回两个对象回去

为了避免这种情况,我们还需要加入关键字volatile(禁止指令重排序与保证可见性)

class Teacher{
//这里加上volatile 后就没有排序的问题了private static volatile Teacher te = null;private Teacher(){}public static synchronized Teacher getInstance(){if(te == null){te  = new Teacher();}return te;}
}

实际上到了这一步

我们已经解决安全的问题了

但是为了进一步提升效率,我们采取了双if判断的方式

双if判断

我们把锁加在了if判断语句这里,而取消了get方法的锁

让多个线程同时调用该方法,如果没有被创建,则执行上锁的new对象操作

如果已经被创建则返回该对象

class Teacher{private static volatile Teacher te = null;private Teacher(){}public static  Teacher getInstance(){//第一个if判断,如果已经创建锁,就直接跳到最后的返回if(te == null){//多个线程在调用get的时候,都卡在这里竞争这把锁
//竞争成功的创建唯一对象,并释放锁
//其他线程拿到被释放的锁之后进去查看,发现第一个线程已经创建了唯一对象
//不满足第二个if条件,又跳到最后返回synchronized(Teacher.class){if(te == null){te  = new Teacher();}}}return te;}
}

但我个人感觉,用前面的volatile和对get方式加锁已经足够了

虽然效率比双if要低一些但已经解决了我们的多线程安全问题

双if判断只能说锦上添花吧


http://chatgpt.dhexx.cn/article/aYJCIR11.shtml

相关文章

java设计模式之单例模式|单例模式之饿汉模式、懒汉模式、枚举方式|最详细的6种懒汉模式详解

目录 一、单例模式 二、饿汉模式和懒汉模式 1、饿汉模式,线程安全 2、懒汉模式 懒汉模式1,线程不安全(不常用) 懒汉模式2,线程安全(不常用) 懒汉模式3,线程安全,双…

全志F1C100s主线linux入坑记录 (10)调试串口更改

调试串口更改 百度网站 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 调试串口更改前言uboot 修改一、修改设备树二、修改文件3. 修改内核传递参数 内核修改参考 前言 未完成版本 未完成版本 未完成版本 未完成…

f1c100s 调试问题汇总

问题 usb无法识别 windows显示无法识别的usb设备 解决: 卸载设备,插拔一下,就可以识别了,之后就会自动安装驱动。 umount失败 fuser ./d2 可以显示出当前哪个程序在使用磁盘上的某个文件、挂载点、甚至网络端口,并…

【f1c200s/f1c100s】FT5426触摸屏驱动适配

【f1c200s/f1c100s】FT5426触摸屏驱动适配 前言设备树配置IIC控制器FT5426设备树配置 内核配置结果 前言 嵌入式linux下的触摸屏驱动是基于input子系统的,当触摸发生时,内核上报触摸事件至用户层。我使用的显示屏是正点原子的7寸RGB接口显示屏&#xff…

f1c100s开发笔记

f1c100s开发笔记 全志芯片相关的论坛帖f1c100s移植帖交叉编译器的安装uboot的编译适配配置开始编译uboot编译遇坑 2020-05-20 09:56:15 星期四 全志芯片相关的论坛帖 https://whycan.cn/t_3019.html#p25005 f1c100s移植帖 https://whycan.cn/t_3211.html 交叉编译器的安装 …

全志F1C100S/F1C200S学习笔记(1)——基础简介及资料

文章目录 一、芯片概览二、芯片框图三、芯片规格四、资料:五、仓库:一、芯片概览 二、芯片框图 三、芯片规格 功能描述CPUARM9 CPU architecture16KByte D

f1c100linux系统吗,全志F1C100s怎么样 F1C100s芯片参数介绍

全志F1C100s芯片怎么样,F1C100s处理器好用吗?F1C100s是720P高清多媒体处理器。下面带来F1C100s芯片的具体参数,准备入手搭载F1C100s芯片设备的用户可以参考一下。 F1C100s芯片架构图 F1C100s特性介绍 支持H.264 1920x108030fps 解码 支持MJPE…

全志F1C100S的BROM研究

全志f1c100s是个性价比很高的芯片,但是对一般人不太友好的是它的资料开放的太少了。 网上找不到完整版的用户手册,只能从有限的手册文档和参考代码旁敲侧击,反向猜测。 关于它的BROM网上的手册内容很少。 手册上只有短短3句话: 具…

10、Lctech Pi(F1C200S)驱动电阻屏触摸芯片ns2009(ts2007),buildroot配置tslib(CherryPi,Mangopi,F1C100S)

本次主要参考: https://github.com/mangopi-sbc/buildroot-mangopi-r https://blog.csdn.net/qq_35031421/article/details/113436888 https://blog.csdn.net/dancheqishi23/article/details/116498088 (如果方便请给这几位大佬一个关注) 开…

F1C100S自制开发板调试过程

疫情,等了好久板子终于到了。 我这里使用的是坑网大佬提供的tiny200开发包,用的芒果派R3配置文件 1,配置其的介质,我板子上用的是nor-spi-flash,所以需要在设备树里面屏蔽掉nand-flash相关的节点,否则启动会有错误。 …

F1C100S(Lichee Nano)触摸屏 (GT9147)

1、前提 Ubuntu 环境版本 (18.04) Linux ubuntu 5.4.0-131-generic #147~18.04.1-Ubuntu SMP Sat Oct 15 13:10:18 UTC 2022 x86_64 x86_64 x86_64 GNU/LinuxARM GCC版本 gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)F1C100S Linux版本 (linux-nano-5.2-tf) 链接 …

全志F1C100s主线linux入坑记录 (5)LVGL8.2移植

LVGL8.2移植 百度网站 文章目录 LVGL8.2移植一、安装VScode二、安装lvgl模拟器二、F1c100s 移植lvgl参考 一、安装VScode 进入VScode官网下载安装包,如果最新版本安装有问题可以安装老版本的 https://code.visualstudio.com/使用命令行安装VScode sudo dpkg -i …

全志F1C100s主线linux入坑记录 (7)GBA模拟器移植

GBA模拟器移植 百度网站 文章目录 GBA模拟器移植一、下载gpsp 源代碼二、gpsp环境配置参考 一、下载gpsp 源代碼 gpsp源码 解压文件 7z x gpsp.7z 二、gpsp环境配置 gpsp需要SDL环境我们先在bulidroot中添加SDL包 make menuconfigTarget packages ---> Graphic libra…

9、Lctech Pi(F1C200S)开启I2C0(CherryPi,Mangopi,F1C100S)

本次主要参考: https://github.com/mangopi-sbc/buildroot-mangopi-r https://wiki.sipeed.com/soft/Lichee/zh/Nano-Doc-Backup/index.html (如果方便请给这几位大佬一个关注) 注意代码块之间的空行 配置设备树文件 1、打开linux-5.7.1/a…

全志F1C100s主线linux入坑记录 (3)适配其他分辨率的LCD

适配其他分辨率的LCD 百度网站 文章目录 适配其他分辨率的LCD一、修改U-boot屏幕参数二、修改linux内核文件三、测试效果 一、修改U-boot屏幕参数 修改对应屏幕的参数(我这里是1024*600的屏幕) 修改 -> ARM architecture -> Enable graphical ub…

全志F1C100S从零开发记录(1)

1.刚买到板子,开箱如下图所示: 2.管脚焊接(焊接串口,用来看串口打印信息),5v供电: 3.通过usb转ttl接到电脑上: . 4.设置串口波特率115200 ,打开串口,上电出…

7、Lctech Pi(F1C200S)开启RNDIS,通过USB与电脑联网(CherryPi,Mangopi,F1C100S)

本次主要参考: 荔枝nano开启RNDIS驱动,无需补丁。 https://github.com/peng-zhihui/Planck-Pi#head23 https://github.com/mangopi-sbc/buildroot-mangopi-r https://www.cnblogs.com/listenscience/p/13758272.html (如果方便请给这几位大佬…

全志F1C200S F1C100S 介绍

很久以前发现了一颗性价比极高而且比较好玩的SOC,加群请仔细阅读本博客(见DKTool界面,请备注“来自博客”) 那就是全志F1C100S F1C200S,其中F1C100S内置32MB DDR1内存,F1C200S内置64MB DDR1内存。 这个片…

6、Lctech Pi(F1C200S)4.3寸(480*272)16位RGB565LCD屏驱动适配(CherryPi,Mangopi,F1C100S)

本次主要参考: https://blog.csdn.net/wending1986/article/details/106837597/ http://blog.chinaunix.net/uid-20543672-id-3246283.html https://wiki.sipeed.com/soft/Lichee/zh/Nano-Doc-Backup/index.html 李山文大佬 (如果方便请给这几位大佬一个…

【F1C100S】编译启动所需的uboot,kernel,rootfs

个人画了块没有连接任何其他模块的F1C100S开发板,没有链接任何外设,本文是编译所有启动所需的三大件。(只要编译出三个东西复制到sd卡就可启动,不需要制作成镜像img文件) 环境:使用安装了ubuntu18的电脑进…