多线程06 单例模式,阻塞队列以及模拟实现

news2025/1/24 17:52:45

前言

上篇文章我们讲了wait和notify两个方法的使用.至此,多线程的一些基本操作就已经结束了,今天我们来谈谈多线程的一些简单应用场景.

单例模式

单例模式,顾名思义,只有一个实例的模式,我们有两种实现方式,分别是懒汉式和饿汉式,我们来分别给出代码.

饿汉式(此处的饿表示创建实例的迫切,所以我们定义成一个类变量即可,然后提供他的私有构造方法,提供获取实例的方法,由于是随着类的加载而加载,所以该实例是无线程安全问题的.)

class singleTon{
    private static singleTon instance = new singleTon();
    public static singleTon getInstance(){
        return instance;
    }
    private  singleTon(){

    }
}

懒汉式(需要的时候再创建,这个是在第一次使用的时候再创建实例,就有可能引发线程安全的问题,下面我给出代码)

class SingleTonLazy{
    //引用指向唯一实例
    private static volatile SingleTonLazy instance = null;
    private static final Object lock = new Object();
    public static SingleTonLazy getInstance(){
        if(instance == null){
            synchronized (lock){
                if(instance == null){
                    instance = new SingleTonLazy();
                }
            }
        }
        return instance;
    }
    private SingleTonLazy(){

    }
}

你可能会想,这里为啥判断了两次instance不为空,并且又加了一个锁呢??

1.首先,内层if是判断是否要创建instance对象

2.加锁的原因是在多线程的情况下,可能cpu调度到线程1后执行了一个判断,就去调度到线程2了,然后再次调度到线程1时,又创建了一个实例,此时这个锁是为了帮助判空创建对象的操作保证原子性的

3.最后一个if其实是为了不让每次都持有和释放锁,只有第一次持有和释放锁,来降低锁的消耗

阻塞队列

下面我们介绍一下阻塞队列,基于这个就构成了当前经常使用的 - 消息队列

其实在日常生活中,它的使用很多,比如举例如下

淘宝等商城软件,在首页要获取到用户信息和商品信息

这样假设用户信息服务器挂了,可能导致整个服务挂了

此时我们引入消息队列

让请求接收服务器直接将请求放到信息队列中,让其他的服务器依次来取即可

好处

1.降低了服务器之间的耦合度,此时如果添加服务器可以直接添加,一个服务器宕机对其他的服务影响小

2.削峰填谷

请求多的时候,可以先存放在消息队列中慢慢处理

下面我们来简单实现一个简易消息队列(基于循环队列)

class MyBlockingQueue{
    private String[] elems = null;
    private int head = 0;
    private int tail = 0;
    private int size = 0;

    private  final  Object lock = new Object();

    public MyBlockingQueue(int capacity) {
        elems = new String[capacity];
    }
    public void put(String elem) throws InterruptedException {
        synchronized (lock){
            while (size >= elems.length){
                //满了需要阻塞
                lock.wait();
            }
            //加元素
            elems[tail] = elem;
            tail++;
            if(tail>=elems.length){
                tail = 0;
            }
            //使用elem % elems.length也行
            size++;
            lock.notify();
        }
    }
    public String take() throws InterruptedException {
        synchronized (lock){
            while(size == 0){
                lock.wait();
                //阻塞
            }
            String elem = elems[head];
            head++;
            if(head>= elems.length){
                head = 0;
            }
            size--;
            lock.notify();
            return elem;
        }

    }
}

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

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

相关文章

【Spring】AOP实现公共字段填充

目录 1. 公共字段自动填充 1.1 问题分析 1.2 实现思路 1.3 代码开发 1.3.1 步骤一 1.3.2 步骤二 1.3.3 步骤三 1.4 功能测试 1.5 代码提交 1. 公共字段自动填充 1.1 问题分析 在上一章节我们已经完成了后台系统的员工管理功能和菜品分类功能的开发,在新…

L1-015:跟奥巴马一起画方块

题目描述 美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方…

实时流式计算 kafkaStream

文章目录 实时流式计算Kafka StreamKafka Streams 的关键概念KStreamKafka Stream入门案例编写SpringBoot 集成 Kafka Stream 实时流式计算 一般流式计算会与批量计算相比较 流式计算就相当于上图的右侧扶梯,是可以源源不断的产生数据,源源不断的接收数…

西南科技大学模拟电子技术实验四(集成运算放大器的线性应用)预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结果,不得分,页数可根据内容调整) 反相比例运算电路(1)实验…

Azure Machine Learning - 使用 Azure SDK 进行全文搜索

了解如何使用 Azure SDK 中的 Azure.Search.Documents 客户端库创建、加载和查询使用示例数据的搜索索引,实现全文搜索。 全文搜索使用 Apache Lucene 进行索引和查询,使用 BM25 排名算法对结果进行评分。 关注TechLead,分享AI全维度知识。作…

linux 安装go环境

下载go SDK All releases - The Go Programming Language 此处建议选择与本机windows一样的版本,便于调试,若不涉及本地windows,则忽略此提示 上传到linux 解压go SDK 执行下述命令进行解压 tar -xvf go1.19.linux-amd64.tar.gz 此处选择…

万能的视频格式播放器

今天博主给大家带来一款“万能”的视频播放器——VLC Media Player,支持的文件格式非常多,大家快来一起看看吧! VLC Media Player 是一款可播放大多数格式,而无需安装编解码器包的媒体播放器。可以播放 MPEG-1、MPEG-2、MPEG-4、D…

Linux的基本指令(五)

目录 前言 tar指令(重要) 再次思考,为什么要打包和压缩呢? 实例:基于xshell进行压缩包在Windows与Linux之间的互传 实例:实现两个Linux系统之间的文件互传 bc指令 uname -r指令 重要的热键 关机与开机 扩展命令 shell及…

MediaPipe 3D姿态估计简明教程

姿势检测是更多地了解视频和图像中人体的重要一步。 我们现有的模型支持 2D 姿态估计已经有一段时间了,你们中的许多人可能已经尝试过。 今天,我们在 TF.js 姿势检测 API 中推出第一个 3D 模型。 3D 姿态估计为健身、医疗、动作捕捉等应用开辟了新的设计…

深度学习记录--计算图(前向后向传播)

什么是计算图? 从一个例子入手: 将函数J的计算用流程图表示出来,这样的流程图被称为计算图 简单来说,计算图是用来显示每个变量间的关系的一种图 两种传播方式 计算图有两种传播方式:前向传播 和 后向传播 什么是前…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于多场景模糊集和改进二阶锥方法的配电网优化调度》

这个标题涉及到配电网(Distribution Network)的优化调度问题,其中使用了两个关键的方法:多场景模糊集和改进二阶锥方法。 多场景模糊集: 多场景: 这可能指的是在考虑不同情景或条件下的配电网运行状态。每个…

智能优化算法应用:基于蝠鲼觅食算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于蝠鲼觅食算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于蝠鲼觅食算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蝠鲼觅食算法4.实验参数设定5.算法结果6.参考…

算力基础设施领域国家标准发布

2023 年 11 月 27 日,国家标准 GB/T 43331-2023《互联网数据中心(IDC)技术和分级要求》正式发布。这一国家标准由中国信息通信研究院(简称“中国信通院”)联合多家企事业单位编制,旨在满足当前国家算力基础…

逸学java【初级菜鸟篇】12.网络通讯编程

hi,我是逸尘,一起学java吧 目标(任务驱动) 请练掌网络通讯的内容。 局域网和互联网 局域网英文:Local Area Network,缩写:LAN,是指一群通过一定形式连接起来的计算机,…

Gradio库的安装和使用教程

目录 一、Gradio库的安装 二、Gradio的使用 1、导入Gradio库 2、创建Gradio接口 3、添加接口到Gradio应用 4、处理用户输入和模型输出 5、关闭Gradio应用界面 三、Gradio的高级用法 1、多语言支持 2、自定义输入和输出格式 3、模型版本控制 4、集成第三方库和API …

电子产品老化测试方法

电子产品老化测试是为了评估电子设备在长时间使用后的性能变化和稳定性。测试的原理是通过模拟实际情况中的磨损、环境变化等因素,以验证产品在实际使用中的可靠性和耐久性。以下是一些常见的电子产品老化测试方法和其应用: 热老化测试:将设备…

nodejs基于vue的社区物业缴费报修管理系统7vwc6

运行软件:vscode 前端nodejsvueElementUi 语言 node.js 框架:Express/koa 前端:Vue.js 数据库:mysql 开发软件:VScode/webstorm/hbuiderx均可 数据库用MySQL,后台用vue框架 基本要求: 1. 对项目进行详细实际的需求分析。 2. 在网…

pandas基础操作2

数据读取 我们想要使用 Pandas 来分析数据,那么首先需要读取数据。大多数情况下,数据都来源于外部的数据文件或者数据库。Pandas 提供了一系列的方法来读取外部数据,非常全面。下面,我们以最常用的 CSV 数据文件为例进行介绍。 …

前端笔记(一):HTML5 入门学习

前言: 在完成 Java 的 SpringBoot 学习并练习了几个项目后,出于对编程的兴趣和没有组织的局限性,为了开发一些个人的小项目,我将开始前端部分的学习,预计会学到 Vue 框架,同时会把自己的学习笔记发布成博客…

赤龙ERP项目

目录 ERP简介 (1)软件永久免费、持续迭代、gitee开源,github开源 (2)实现主流程的业务和财务闭环 (3)完备的文档,易于部署和二次开发 技术与平台 SpringBoot2MySQLRedisJDK1.8Tom…