多线程知识笔记(五)_单例模式

news2024/10/3 8:31:11

文章目录

  • 1、什么是单例模式
  • 2、饿汉模式
  • 3、懒汉模式

1、什么是单例模式

单例模式是一种设计模式。
什么是设计模式呢?设计模式就是一种模板,就像做饭的时候,新手做饭什么调料都是一把放进锅里,有的菜就讲究调料的先后顺序,这时候把做这道菜的调料顺序告诉新手,新手按照这个顺序去做菜,就可以做出味道好的菜。而放调料的顺序就是设计模式, 它是由有经验的人总结完出来的,为的就是让后来的人能更方便的使用,按照他们写的这个方法做,可以少走很多弯路。
其实设计模式本质上就是“规则”。


单例模式又可以分为两种:饿汉模式和懒汉模式。 单例模式能够保证某个类在程序中只存在唯一 一份实例,而不会创建出多份实例。

2、饿汉模式

饿汉模式的核心是类加载的同时就创建了实例。

//饿汉模式下的单例模式
class single{
    private static single hungry = new single();//类加载时期就已经创建好对象,且只能创建一次

    public static single getInstance(){
        return hungry;
    }
    private single(){
        
    }//禁止外部new对象
}
注意: 1. static是让当前hungry 属性是类属性了,类属性是长在类对象上的,类对象又是唯一实例的(只是在类加载阶段被创建出的一个实例); 2. 构造方法设为private,外面的代码无法从外部new对象; 3. 类对象本身和static没什么关系,只是因为在类里面使用static修饰的成员会作为类的属性,也就是这个属性对应的内存空间是在类对象里面

举个例子:

    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
        a1.x = 10;
        a2.x = 20;

        a1.y = 100;
        a2.y = 200;
        System.out.println(a1.x);
        System.out.println(a2.x);
        System.out.println(a1.y);
        System.out.println(a2.y);
    }
}
class A {
    int x;
    static int y;

结果:
在这里插入图片描述
我们会发现,不同的实例对象去修改静态属性的变量,发现最终结果都一样;
在这里插入图片描述

3、懒汉模式

懒汉模式的核心是什么时候用到对象什么时候在创建对象
看代码:
版本一:

//懒汉模式下的单例模式
class singleLazy{
    private volatile static singleLazy singlelazy= null;//将对象初始化为空
    public static singleLazy getInstance(){   //用static保证对象只能创建一次
         if(singlelazy == null){
               singlelazy = new singleLazy();
           }
        return singlelazy;
    }
}

但是如果这样写,懒汉模式是不安全的,因为上述代码涉及到两个操作:

在这里插入图片描述
当同一个线程有两个操作的时候他就存在线程安全问题!
在这里插入图片描述
所以,此时我们就要加锁来保证读和写是原子性的
版本二:

class singleLazy{
    private static singleLazy singlelazy= null;//将对象初始化为空
    public static singleLazy getInstance(){   //,用synchronized保证线程安全并且对象只能创建一次
        //只要进入getInstance就加锁
            synchronized (singleLazy.class){
                if(singlelazy == null){
                    singlelazy = new singleLazy();
                }
            }
        
        return singlelazy;
    }

}

上面的代码确实保证了线程安全,但是加锁也是有开销的,除了第一次要创建实例以外,后序再次调用getInstance,此时singlelazy一定都是非空的,再去加锁就浪费了大量的开销,所以我们应该直接返回;
看代码:版本三

class singleLazy{
    private static singleLazy singlelazy= null;//将对象初始化为空
    public static singleLazy getInstance(){  
        if(singlelazy == null){//一旦不为空,就说明已经new过对象了,就直接返回
            synchronized (singleLazy.class){ //用synchronized保证线程安全并且对象只能创建一次
                if(singlelazy == null){
                    singlelazy = new singleLazy();
                }
            }
        }
        return singlelazy;
    }

}

调试一下:

public class Test1 {

    public static void main(String[] args) {
        singleLazy s1 = singleLazy.getInstance();
        singleLazy s2 = singleLazy.getInstance();//利用singlelazy new了两个对象
        System.out.println(s1 == s2);//true
    }
}

结果:
在这里插入图片描述
结果两个对象的地址是相同的,所以他们就是一个对象,new第二个对象的时候,发现已经new过对象了,所以直接将s1返回了;

但是这样写代码还是会有一个bug,但是是在 多线程环境下才有的问题,new对象有三个步骤:
在这里插入图片描述

所以此时我们就需要用到一个非常重要的关键字,volatile他有两个非常重要的作用。1、解决内存可见性的问题,2、禁止指令重排序。
看代码:

class singleLazy{
    private volatile static singleLazy singlelazy= null;//将对象初始化为空
    public static singleLazy getInstance(){   //,用synchronized保证线程安全并且对象只能创建一次
        if(singlelazy == null){//一旦不为空,就说明已经new过对象了,就直接返回
            synchronized (singleLazy.class){
                if(singlelazy == null){
                    singlelazy = new singleLazy();
                }
            }
        }
        return singlelazy;
    }

}

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

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

相关文章

Java web 2022跟学尚硅谷(十一) Vue基础和Axios基础和json基础

Java web 2022跟学尚硅谷十一后端基础 书城Vue在js中定义对象的2种方式方式一方式二简单的Vue代码绑定元素的属性方式一 v-bind:value方式二 :value双向数据绑定 v-model:方式一方式二 :value可以省略,trim去除首尾空格条件渲染 v-if条件渲染 v-else条件渲染 特别注…

[附源码]Python计算机毕业设计高校医务管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

极地土活性层和永久冻土的比较宏基因组学

北极地区有大约87%由低有机碳矿物土壤组成,但对低碳永久冻土(PF)和活性层(AL)土壤中微生物活性的了解仍然有限。多种物理和生物因素可能影响碳循环,包括土壤化学、氮等养分的可用性以及现有微生物群落的结构…

论文解析[9] Swin Transformer: Hierarchical Vision Transformer using Shifted Windows

发表时间:2021 论文地址:https://arxiv.org/abs/2103.14030 代码地址:https://github.com/microsoft/Swin-Transformer 文章目录摘要3 方法3.1 总体框架3.2 基于自注意力的移动窗口3.3 结构变形5 结论摘要 这篇论文提出了一个新的ViT叫作Swi…

大数据培训kettle安装部署

kettle安装部署和使用 2.1 kettle安装地址 官网地址 https://community.hitachivantara.com/docs/DOC-1009855 下载地址 https://sourceforge.net/projects/pentaho/files/Data%20Integration/ 2.2 Windows下安装使用 2.2.1 概述 在实际企业开发中,都是在本…

Html 小功能总结二

文章目录一、Html 实现弹窗的实例二、Html 实现流程图三、制作一个简单的菜单功能一、Html 实现弹窗的实例 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><title></title><style type"text/css">body…

C++ Reference: Standard C++ Library reference: Containers: map: map: crbegin

C官网参考链接&#xff1a;https://cplusplus.com/reference/map/map/crbegin/ 公有成员函数 <map> std::map::crbegin const_reverse_iterator crbegin() const noexcept;返回指向反向开始的const_reverse_iterator 返回一个指向容器中最后一个元素的const_reverse_ite…

Nacos 消息通知系统 源码讲解

目录 1. 介绍 2. Nacos 中的生产者 3. Nacos 中的消费者 4. Nacos 中的事件 5. 统一事件通知中心 NotifyCenter 6. 总结 1. 介绍 Nacos 节点内部使用了大量的事件机制进行通信&#xff0c;这样各种操作进行了解耦&#xff0c;提高了性能。 接下来就介绍。 所谓事件机制…

virtualenv系列 (5) · 打通virtualenvwrapper和PyCharm/IntelliJ IDEA的虚拟环境

PyCharm/IntelliJ IDEA已经内置了对virtualenv的支持&#xff0c;当我们为一个项目创建一个新的Python SDK时&#xff0c;就会进入到Add Python Interpreter对话框&#xff0c;选择Virtualenv Environment -> New environment就将创建一套新的virtualenv环境。这里&#xff…

关于长三角某高校能效管理平台应用成效探讨

更多请关注&#xff1a;安科瑞电气网 摘要&#xff1a; 随着现代科学技术的发展&#xff0c;在高校中开始广泛应用智能化技术&#xff0c;改善学生宿舍的用电管理模式&#xff0c;提高宿舍的管理水平&#xff0c;有利于实现高校宿舍用电管理的科学化。本文主要阐述传统高校宿…

D2. Seating Arrangements (hard version)(贪心+排序)

Problem - 1566D2 - Codeforces 这是该问题的困难版本。唯一的区别是&#xff0c;在这个版本中&#xff0c;1≤n≤300。 电影院的座位可以表示为有n行和m列的表格。每行的座位都用1到n的整数编号&#xff0c;从左到右连续编号&#xff1a;在第k行&#xff0c;从m(k-1)1到mk&am…

前端的视角聊聊如何快速入门Python

对于 NodeJs 开发的小伙伴&#xff0c;使用 node-gyp 将 C 模块转换成 NodeJs 的 addon 插件时会依赖 Python 的安装环境&#xff08;针对使用了 nvm 等版本管理工具的情况&#xff09;。对于前端小伙伴来说&#xff0c;Python 本身确实不是一个必须学习的语言&#xff0c;但也…

提前做好网络安全分析,运维真轻松(一)

背景 某汽车总部已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和历史原始流量。汽车配件电子图册系统是某汽车集团的重要业务系统。本次分析重点针对汽车配件电子图册系统进行预见性分析&#xff0c;以供安全取证、性能分析、网络质量监测以及深层网络分析…

SQL基础——聚合与排序

聚合与排序前言思维导图聚合函数示例表3-1![在这里插入图片描述](https://img-blog.csdnimg.cn/9c286053f87a4ae882bece8128bdcab5.png)计算表中数据的行数 COUNT函数示例代码3.1 计算全部数据的行数执行结果计算NULL之外的数据的行数代码示例3.2 计算NULL之外的数据行数执行结…

【DevOps实战系列】第五章:基于Gitlab/Maven/Jenkins/Docker实战案例详解

个人亲自录制全套DevOps系列实战教程 &#xff1a;手把手教你玩转DevOps全栈技术 从创建Jenkins的job开始 1.gitlab设置&#xff1a; 我们从新建一个jenkins任务开始&#xff0c;建一个自由风格项目&#xff0c;我们暂时只让他能拉取git的代码。 路径&#xff1a;从gitlab上新…

【ML笔记】5、支持向量机(SVM)

支持向量机&#xff08;SVM&#xff09;是一个强大的和通用的ML模型&#xff0c;能够执行分类&#xff0c;回归&#xff0c;甚至异常值检测&#xff0c;特别适合于复杂的中小型数据集。 1、线性SVM分类 我们可以看到&#xff0c;这两个类可以很容易地用一条直线(线性可分)分开…

GAN入门知识

GAN入门知识 结构 正式说 GAN 之前我们先说一下判别式模型和生成式模型。 判别器 判别式模型 判别式模型&#xff0c;即 Discriminative Model&#xff0c;又被称为条件概率模型&#xff0c;它估计的是条件概率分布(conditional distribution)&#xff0c; p(class|context) 。…

图书网上商店

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 1

docker-compose安装部署kafka

文章目录前言一、环境信息二、准备部署1.准备路径2.安装docker-compse&#xff0c;下载镜像3.生成yml文件2.执行部署三、登陆页面前言 记录一下使用docker-compose部署kafka平台的过程 参考&#xff1a;https://blog.csdn.net/QQ83512272/article/details/126368978 一、环境信…

Socket Websocket 客户端和服务端实现

最近在写一个上位机&#xff0c;用到了Websocket&#xff0c;这里就整理一下&#xff0c;顺便把Socket的东西也整理的了&#xff0c;方便以后查阅。 Socket Websocket 客户端和服务端实现Socket客户端和服务端实现Socket客户端Socket服务端实现效果Websocket 客户端和服务端实现…