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.class
    public static synchronized void Test(){

    }

    //2.使用在非静态方法上,此时锁的对象是当前类的对象 => this
    public 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代码块中使用当前类对象作为锁定对象,可以保证在多线程环境下只有一个线程能够进入该代码块,从而实现对象的单例模式。这是因为类对象是唯一的,所有线程都可以通过该对象来同步访问代码块。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

真心希望所有行政人都能刷到啊

行政的姐妹在哪里啊?这个打工工具真的要知道哦! 信我,真的好用啊!终于不用自己写总结写材料的啊! 这东西写啥都可以,只要输入需求马上就写好了啊,什么工作总结,活动策划方案&#…

如何解决苹果应用商城审核拒绝的Guideline 2.1 - Information Needed问题

当你的应用程序在苹果应用商城审核过程中被拒绝时,苹果会向您发送一封邮件,其中提供了关于拒绝原因的详细信息。本文将指导您如何正确处理Guideline 2.1 - Information Needed问题,并提供解决方案,以确保您的应用程序能够通过审核…

数据智慧:如何利用可视化提升效率

数据可视化是一项强大的工具,能够显著提高工作效率和决策的准确性。下面我就以可视化从业者的角度,简单谈谈数据可视化是如何助力效率提升的。 直观理解复杂数据 数据可视化将抽象的数据转化为图表、图形或仪表盘,使数据更易于理解。这种直观…

【一周安全资讯1216】欧盟就AI监管《人工智能法案》达成历史性协议;赛迪发布《中国网络安全测评服务市场研究报告 (2023)》

要闻速览 1、欧盟就全球首个AI监管《人工智能法案》达成历史性协议 2、我国牵头提出的国际标准《信息技术 网络安全 第7部分:网络虚拟化安全指南》正式发布 3、《粤港澳大湾区(内地、香港)个人信息跨境流动标准合同实施指引》发布 4、赛迪顾…

美团外卖商超商品销量数据

美团外卖商超商品月销量 字段名 店铺id 店铺名称 商品id 商品名称 商品分类 规格名 原价 现价 月销 规格属性 描述 商品图片 含商家月销量

PyCharm添加自动函数文档注释

目录 1、背景2、开启PyCharm自动函数文档注释 1、背景 规范的函数文档注释有助于他人理解代码,便于团队协作、提高效率。但如果我们自己手写函数文档注释将非常耗时耗力。PyCharm安装后默认没有开启自动化函数文档注释,需要我们开启 2、开启PyCharm自动…

【Python可视化系列】一文教会你绘制美观的直方图(理论+源码)

一、引言 前面我详细介绍了如何绘制漂亮的折线图和柱状图: 【Python可视化系列】一文彻底教会你绘制美观的折线图(理论源码) 【Python可视化系列】一文教会你绘制美观的柱状图(理论源码) 对于一个连续性的变量&#xf…

前端的薪资怎么样?

前端开发工程师其实包括了很多,web端、移动端等都属于前端开发。所以无论是互联网、电商、教育,还是医疗、金融、社交等行业,前端都是必不可缺的,只是由于经济的不景气无形中拔高了前端开发的准入门槛。 前端开发的工作内容不仅仅…

多维时序 | MATLAB实现SSA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现SSA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现SSA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现SSA-CNN-LST…

如何在公网环境下使用Potplayer访问本地群晖webdav中的影视资源

文章目录 本教程解决的问题是:按照本教程方法操作后,达到的效果是:1 使用环境要求:2 配置webdav3 测试局域网使用potplayer访问webdav3 内网穿透,映射至公网4 使用固定地址在potplayer访问webdav ​ 国内流媒体平台的内…

@德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?

德人合科技 | 天锐绿盾加密软件是一款全面保障企业电脑数据和安全使用的加密软件 PC端访问地址:www.drhchina.com 它的功能包括但不限于: 实时操作日志:可以实时详细地记录所有终端的操作日志,包括终端上窗口标题的变换、程序的…

JS面试题

JavaScript 面试题汇总 1. 根据下面 ES6 构造函数的书写方式,要求写出 ES5 的 class Example { constructor(name) { this.name name;}init() { const fun () > { console.log(this.name) }fun(); } } const e new Example(Hello); e.init();参考答案&…

位操作符详解(C语言)

前言 C语言中的位操作符是用来对数据的二进制表示进行位级操作的运算符。这些操作符包括位与(&)、位或(|)、位异或(^)、位取反(~),这些位操作符可以用来进行各种位级…

家里就一台电脑还抢着用,限定电脑投屏解决了问题。

很多人都遇到过家里电子设备争抢的情况吧。上周我就因为临时任务,需要用电脑处理一些文件,搜索、浏览资料,制作对应PPT,无论哪项都需要用电脑。恰巧,家里小孩有个观看《大国崛起》纪录片的学习任务,带完整字…

C++继承与派生——(1)继承的层次关系

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝 再好的种子,不播种下去&am…

摄像头画面作为电脑桌面背景

1. 创建文件main.pyw,文件内容 import base64 import io import os import threading import tkinter as tkimport cv2 import pystray import win32api import win32con import win32gui from PIL import Image, ImageTk from pystray import MenuItem, Menuclass…

Kubernetes 架构原则和对象设计

什么是 Kubernetes Kubernetes 是谷歌开源的容器集群管理系统 • 基于容器的应用部署、维护和滚动升级; • 负载均衡和服务发现; • 跨机器和跨地区的集群调度; • 自动伸缩; • 无状态服务和有状态服务; • 插件机制…

多表插入操作——后端

场景:当添加一个菜品时,还需要记录菜品的口味信息,因此需要对菜品表(dish)和口味表(dish_flavor)同时进行插入操作。 两个表的字段: 代码思路:由DishController将前端的…

多个文件保存路径不同,如何批量改为相同的文件名称并添加编号

大伙在日常工作中有没有遇到需要修改文件名称吗?平时遇到修改文件名称是如何操作呢,是按比较重统的方法操作,点右键重命名,这个方法是可以使用,如果量少情况可以使用这个方法操作,如果量大,文件…

防火墙-iptables详解

前言:最近的工作中,需要对防火墙进行配置,但是很多地方都是老机器,有的用iptables,有的用firewalld,我写下这篇文章,彻底地了解这两个应用软件的使用方法。在以后的工作中,相信很多人…