第四章 单例模式

news2024/9/21 3:33:42

文章目录

  • 前言
  • 一、单例模式的介绍
  • 二、单例模式的 8 种实现方式(懒汉式要注意线程安全问题)
    • 1、饿汉式(静态常量)
      • 优缺点:可能会造成内存的浪费,但也只能浪费内存
    • 2、饿汉式(静态代码块)
    • 3、懒汉式(线程不安全)不推荐
      • 缺点:多线程不安全
    • 4、懒汉式(线程安全,同步方法)添加 synchronized 关键字
      • 缺点效率太低
    • 5、懒汉式(同步代码块)不能使用,解决不了线程安全问题
    • 6、懒汉式(双重检查加 volatile关键字)推荐使用
    • 7、静态内部类
      • 优缺点
    • 8、使用枚举实现单例懒加载
  • 三、JDKの RunTime 类使用的是单例模式
  • 四、单例模式注意事项和细节说明


前言

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


一、单例模式的介绍

在这里插入图片描述

二、单例模式的 8 种实现方式(懒汉式要注意线程安全问题)

在这里插入图片描述

1、饿汉式(静态常量)

在这里插入图片描述

代码示例

package tanchishell.SJMS;

public class SingletonTest01 {

    public static void main(String[] args) {
//测试
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
    }
}


//饿汉式(静态变量)
class Singleton {
    //1. 构造器私有化, 外部能 new
    private Singleton() {
    }
    //2.本类内部创建对象实例
    private final static Singleton instance = new Singleton();
    //3. 提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance() {
        return instance;
    }
}

输出
true
instance.hashCode=460141958
instance2.hashCode=460141958

优缺点:可能会造成内存的浪费,但也只能浪费内存

在这里插入图片描述

2、饿汉式(静态代码块)

在这里插入图片描述

代码示例


package tanchishell.SJMS;

public class SingletonTest01 {

    public static void main(String[] args) {
//测试
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
    }
}


//饿汉式(静态变量)
class Singleton {
    //1. 构造器私有化, 外部能 new
    private Singleton() {
    }
    //2.本类内部创建对象实例
//    private final static  Singleton instance = new Singleton();
    private static Singleton instance;

    static {
        //使用静态代码块,不再使用 final 修饰为常量
        instance = new Singleton();
    }

    //3. 提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance() {
        return instance;
    }
}

输出

true
instance.hashCode=460141958
instance2.hashCode=460141958

在这里插入图片描述

3、懒汉式(线程不安全)不推荐

在这里插入图片描述

代码示例

package tanchishell.SJMS;

public class SingletonTest01 {

    public static void main(String[] args) {
//测试
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
    }
}


//饿汉式(静态变量)
class Singleton {
    //1. 构造器私有化, 外部能 new
    private Singleton() {
    }
    //2.本类内部创建对象实例
    private static Singleton instance;

    //3. 提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance() {
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

输出

true
instance.hashCode=460141958
instance2.hashCode=460141958

缺点:多线程不安全

在这里插入图片描述

4、懒汉式(线程安全,同步方法)添加 synchronized 关键字

在这里插入图片描述

package tanchishell.SJMS;

public class SingletonTest01 {

    public static void main(String[] args) {
//测试
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
    }
}


//饿汉式(静态变量)
class Singleton {
    //1. 构造器私有化, 外部能 new
    private Singleton() {
    }
    //2.本类内部创建对象实例
    private static Singleton instance;

    //3. 提供一个公有的静态方法,返回实例对象
    /** 添加  synchronized 关键字保证线程安全 */
    public static synchronized Singleton getInstance() {
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

输出

true
instance.hashCode=460141958
instance2.hashCode=460141958

缺点效率太低

在这里插入图片描述

5、懒汉式(同步代码块)不能使用,解决不了线程安全问题

在这里插入图片描述

在这里插入图片描述

6、懒汉式(双重检查加 volatile关键字)推荐使用

在这里插入图片描述
在这里插入图片描述

package tanchishell.SJMS;

public class SingletonTest01 {

    public static void main(String[] args) {
//测试
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
    }
}


//饿汉式(静态变量)
class Singleton {
    //1. 构造器私有化, 外部能 new
    private Singleton() {
    }
    //2.本类内部创建对象实例,添加 volatile 保证有序性和可见性
    private static volatile Singleton instance;

    //3. 提供一个公有的静态方法,返回实例对象
    /** 双重检查加 volatile 关键字 */
    public static Singleton getInstance() {
        if(instance == null){
            synchronized (Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}


输出

true
instance.hashCode=460141958
instance2.hashCode=460141958

7、静态内部类

在类加载时,静态内部类没有调用是不会进行类加载的,当被调用时才会被加载,而且只加载一次,加载时线程安全

在这里插入图片描述

package tanchishell.SJMS;

public class SingletonTest01 {

    public static void main(String[] args) {
//测试
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
    }
}


//饿汉式(静态变量)
class Singleton {
    //1. 构造器私有化, 外部能 new
    private Singleton() {
    }

    //提供一个静态内部类,根据JVM底层机制保证线程安全
    private static class SingletonInstance{
        private static final Singleton INSTANCE = new Singleton();
    }

    //3. 提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance() {
        Singleton instance = SingletonInstance.INSTANCE;
        return instance;
    }
}



输出

true
instance.hashCode=460141958
instance2.hashCode=460141958

优缺点

在这里插入图片描述

8、使用枚举实现单例懒加载

在这里插入图片描述

package tanchishell.SJMS;

public class SingletonTest01 {

    public static void main(String[] args) {
//测试
        Singleton instance = Singleton.INSTANCE;
        Singleton instance2 = Singleton.INSTANCE;
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
        instance.method();
    }
}

enum Singleton{
    INSTANCE;
    public void method(){
        System.out.println("hello,world");
    }
}

输出


true
instance.hashCode=460141958
instance2.hashCode=460141958
hello,world

在这里插入图片描述

三、JDKの RunTime 类使用的是单例模式

在这里插入图片描述
在这里插入图片描述

四、单例模式注意事项和细节说明

在这里插入图片描述

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

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

相关文章

( “树” 之 BST) 538. 把二叉搜索树转换为累加树 ——【Leetcode每日一题】

二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。 二叉查找树中序遍历有序。 538. 把二叉搜索树转换为累加树 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加…

( “树” 之 DFS) 337. 打家劫舍 III ——【Leetcode每日一题】

337. 打家劫舍 III 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root。 除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。…

IDEA社区版搭建Tomcat服务器并创建web项目

IDEA社区版搭建Tomcat服务器并创建web项目 目标 创建Web项目的目录结构可以启动Tomcat服务器编写Servlet并访问成功 问题 IDEA社区版没有创建Web工程的选项IDEA社区版没有Tomcat插件 实现步骤 针对以上两个问题,分步解决 问题一:IDEA社区版没有创建…

《花雕学AI》18:AI绘画尝鲜Prompt Hunt,使用人工智能模型来创造、探索和分享艺术作品

引言: 人工智能是当今科技领域的热门话题,它不仅可以帮助人类解决各种实际问题,也可以激发人类的创造力和艺术感。Prompt Hunt就是一个利用人工智能模型来创造、探索和分享艺术作品的AI绘画网站。它提供了三种不同的模型,分别是S…

Git 分布式版本控制工具

文章目录 Git 分布式版本控制工具课程内容1. 前言1.1 什么是Git1.2 使用Git能做什么 2. Git概述2.1 Git简介2.2 Git下载与安装 TODO3. Git代码托管服务3.1 常用的Git代码托管服务3.2 码云代码托管服务3.2.1 注册码云账号3.2.2 登录码云3.2.3 创建远程仓库3.2.4 邀请其他用户成为…

最火爆的持续集成工具 jenkins ,详细教程来啦(傻瓜式教程)

很多小伙伴在安装以及配置jenkins的时候,总会遇到一些问题。 今天在这边特地把jenkins的安装,以及常用的一些功能的配置整理到了这篇文章中,希望对大家有所帮助! 1安装JDK JDK安装完需要配置环境变量,大家可以自行百度…

Spark学习:spark读写postgreSql

读写PostgreSql 一、环境搭建二、写三、读四、ETL一、环境搭建 1、spark安装包,官网地址,我下的是如下版本 2、postgreSql数据库jdbc驱动,官网地址,我下的是如下版本 3、java版本1.8;scala版本2.12.15 4、spark安装包解压到任意目录,把postgreSql的jdbc驱动jar包放在spark的…

MySQL having关键字详解、与where的区别

1、having关键字概览 1.1、作用 对查询的数据进行筛选 1.2、having关键字产生的原因 使用where对查询的数据进行筛选时,where子句中无法使用聚合函数,所以引出having关键字 1.3、having使用语法 having单独使用(不与group by一起使用&a…

L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事 有趣的数据结构题

传送门:PTA 题目描述: 给定一棵 n 个节点的树,其中节点 r 为根。求该树所有可能的 DFS 序中逆序对数量之和。 输入: 10 5 10 2 2 5 10 7 7 1 7 9 4 2 3 10 10 8 3 6 输出: 516唉,由于近期事情比较多以及某些个人因素导致好久没有更新博客了,今天碰到了一道有意思的…

机器视觉检测技术在工业零部件的应用

众所周知,在工业生产中,传统的检测技术需要大量的检测工作者,不仅影响生产效率,而且带来不可靠的因素。 视觉检测技术克服了传统检测技术的缺点,确保了检测的安全性。 可靠性和自动化程度高,已成为当前检测…

Scrapy配置使用

前人之述备矣 教程:Python虚拟环境ScrapyPyCharm 使用实例 - 知乎 注意:是cmd不是powershell,两者还是有区别的。 因为是本地的虚拟环境,用cmd激活环境并且安装相关的scrapy包,如果用powershell,在pycharm中显示不了…

【MySQL】如何使用MySQL锁(全局锁、表级锁、行级锁)?

文章目录 概述一、全局锁介绍语法特点 二、表级锁介绍表锁元数据锁意向锁 三、行级锁介绍行锁间隙锁&临键锁 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外&#xf…

神经网络之反向传播算法(自适应矩估计算法Adam)

文章目录 自适应矩估计算法(Adam)1、算法原理2、算法实现2.1 训练过程2.2 测试过程及结果 3、参考源码及数据集 自适应矩估计算法(Adam) 自适应矩估计算法从其本质上看可以视作是带有动量项的均方根反向传播算法,一方…

jmeter -- WebService接口压测

WebService简介 webService 一种使用http传输SOAP协议数据的远程调用技术。 SOAP协议 soap请求是HTTP POST的一个专用版本,遵循一种特殊的xml消息格格式。Content-type需设置为: text/xml 与HTTP比较 接口中实现的方法和要求参数一目了然不用担心大小写问题不用担心…

matlab中计算标准差std函数

标准差 标准差(Standard Deviation)是离均差平方的算术平均数(即:方差)的算术平方根。 标准差是方差的算术平方根。标准差能反映一个数据集的离散程度。平均数相同的两组数据,标准差未必相同。 计算公式&…

HCIP之路VLAN

VLAN---虚拟局域网 垃圾流量问题 网络安全问题 VLAN特点 一个vlan就是一个广播域,不同vlan内部的数据无法进行跨广播域通讯 vlan的划分不受地域限制 vlan的实现 主机的网卡一般只能发送和接收无标记帧(Untagged Frame)。Tagged Frame --- 标…

【Linux】生产者消费者模型——阻塞队列BlockQueue

文章目录 一、生产者消费者模型生产消费理解生产消费关系 二、基于blockqueue的生产和消费模型单生产单消费计算随机数计算器任务Task存储任务 多生产多消费 三、总结 一、生产者消费者模型 生产消费理解 引入:举个例子,比如我们学生想买东西&#xff…

Tomcat服务器

1.服务器概念: 服务器是一个容器,可以将任何资源放到服务器中,服务器启动后 外部用户可以通过 ip地址:端口/资源路径 来访问服务器容器内对应的资源 你可以将服务器理解为一个共享文件夹,只要服务器启动了,大家都可…

人社LEAF平台架构及其主要技术架构特点

人社LEAF平台架构及其主要技术架构特点https://wheart.cn/so/home?mindex&id31525d77-de79-11ed-96fa-52540016e6ac 在前面的系列文章中介绍了社会保险管理信息系统核心平台三版(以下简称核三)的技术亮点,这些技术亮点主要是由核三的技…

WebGIS:前端:给出地理范围计算出地图瓦片的行列号

目录 前端代码实现 根据xml配置文件计算出行列号 1、xml配置文件信息样例 2、代码实现 运用到的知识 该文档是根据本人做的项目进行的总结,可能存在知识不准确,仅做参考; 前端代码实现 根据提供一个瓦片服务地址,解析服务的…