Java EE 初阶---多线程(二)

news2025/1/24 11:47:44

目录

四、多线程案例之--单例模式

4.1 单例模式

4.2 怎么去设计一个单例?

 饿汉模式

 懒汉模式

 4.3 两种模式的总结


四、多线程案例之--单例模式

4.1 单例模式

是校招中最常考的设计模式之一.

啥是设计模式?

设计模式好比象棋中的 " 棋谱 ". 红方当头炮 , 黑方马来跳 . 针对红方的一些走法 , 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏 .
软件开发中也有很多常见的 " 问题场景 ". 针对这些问题场景 , 大佬们总结出了一些固定的套路 . 按照这个套路来实现代码, 也不会吃亏 .

 单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例.

这一点在很多场景上都需要. 比如 JDBC 中的 DataSource 实例就只需要一个.

(定义了数据库的用户名,密码,连接串,通过DataSource的实例对象获取数据库的连接)

单例模式具体的实现方式 , 分成 " 饿汉 " " 懒汉 " 两种 .

4.2 怎么去设计一个单例?

1.口头约定

对外提供一个方法,要求大家使用这个对象的时候,通过这个方法来获取

(不靠谱,不采用)

2.使用编程语言本身的特性来处理

首先要分析清楚,在Java中哪些对象是全局唯一的 

.class对象 比如String.class  类对象

 

 

 饿汉模式

既然是单例那么通过new的方式去获取对象是有歧义的 那么就不能让外部去new这个对象

Singleton singleton = new Singleton();
//构造方法私有化
private Singleton(){}
public static Singleton getInstance(){
 return instance;
}//用static修饰方法

private static Singleton instance = new Singleton();
//类似于这种类一加载就完成初始化的方式 称为饿汉模式
//书写简单不易出错

懒汉模式

避免程序启动的时候浪费过多的系统资源,当程序使用这个对象时再对它进行初始化

//定义一个类成员变量
private static SingletonLazy instance = null;
public static SingletonLazy getInstance(){
//在获取成员变量的时候判断是否已经初始创建
//如果没有则创建出来
if(instance == nul){
     instance = new SingletonLazy();
  }
return instance;
}

多线程环境下获取单例对象:

  // 创建多个线程,并获取单例对象
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(() -> {
                // 获取单例对象,并打印
                SingletonLazy instance = SingletonLazy.getInstance();
                System.out.println(instance);
            });
            // 启动线程
            thread.start();
        }
    }
}

                                                                                

 通过检查发现获取到了不同的对象,出现了线程不安全

分析造成线程不安全的原因:

 为了解决这个问题,可以把初始化代码加锁:

public synchronized static SingletonLazy getInstance(){

 可以看到依然出现了线程安全问题,那么就需要扩大锁的力度

 

输出正常、

但是还剩一个非常严重的问题!

 

 举个栗子:

 为了避免过度竞争消耗,加入一层判断

 public static SingletonDCL getInstance() {
        // 为了让后面的线程不再获取锁,避免了锁竞争造成的资源浪费
        if (instance == null) {
            synchronized (SingletonDCL.class) {
                // 完成初始化操作,只执行一次
                if (instance == null) {
                    instance = new SingletonDCL();
                }
            }
        }
        //双重检查锁

通过加synchnized关键字解决了原子性,内存可见性问题,那有序性如何保证?

那么就需要给共享变量加volatile关键字

public class SingletonDCL {
    // 定义一个类成员变量
    private volatile static SingletonDCL instance;

    // 构造方法私有化
    private SingletonDCL() {
    }

    public static SingletonDCL getInstance() {
        // 为了让后面的线程不再获取锁,避免了锁竞争造成的资源浪费
        if (instance == null) {
            synchronized (SingletonDCL.class) {
                // 完成初始化操作,只执行一次
                if (instance == null) {
                    instance = new SingletonDCL();
                }
            }
        }
        // 返回实例对象
        return instance;
    }
}

 4.3 两种模式的总结

 

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

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

相关文章

MaterialDesignInXamlToolkit 初学项目实战(1)首页搭建

前言 最近在学WPF&#xff0c;由于人比较烂&#xff0c;有一个星期没怎么动代码了。感觉有点堕落。现在开始记录WPF项目&#xff0c;使用MaterialDesignInXamlToolkit。 环境搭建 如果没下载MaterialDesign 的源码 github源码运行 在Nuget里面引入MaterialDesign Materia…

【ChatGPT镜像网站+MindShow高效生成PPT,保姆级安装教程】

&#x1f680; AI破局先行者 &#x1f680; &#x1f332; AI工具、AI绘图、AI专栏 &#x1f340; &#x1f332; 如果你想学到最前沿、最火爆的技术&#xff0c;赶快加入吧✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;CSDN-Java领域优质创作者&#x1f3c6;&am…

一、基础算法9:区间合并 模板题+算法模板(区间合并)

文章目录 算法模板离散化题目模板 模板题区间和原题链接题目题解思路 算法模板 离散化题目模板 // 将所有存在交集的区间合并 void merge(vector<PII> &segs) {vector<PII> res;sort(segs.begin(), segs.end());int st -2e9, ed -2e9;for (auto seg : segs…

SD-MTSP:遗传算法GA求解单仓库多旅行商问题(提供MATLAB代码,可以修改旅行商个数及起点)

一、单仓库多旅行商问题 多旅行商问题&#xff08;Multiple Traveling Salesman Problem, MTSP&#xff09;是著名的旅行商问题&#xff08;Traveling Salesman Problem, TSP&#xff09;的延伸&#xff0c;多旅行商问题定义为&#xff1a;给定一个&#x1d45b;座城市的城市集…

SpringSecurity和Shiro---权限设置

在 Web 开发中&#xff0c;安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求&#xff0c;但是应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题&#xff0c;就可能陷入一个两难的境地&#xff1a;一方面&#xff0c;应用存在严重的安全漏洞…

15-JavaScript-内部JS、外部JS、数据类型、关键词

1、内部JS&#xff1a;是在HTML文件中直接嵌入JavaScript代码的一种方式。使用<script>标签来定义JavaScript代码块。通常情况下&#xff0c;我们会将JavaScript代码放在文档的<head>或<body>标签内。 <!DOCTYPE html> <html> <head><…

MySQL-----事务管理

文章目录 前言一、什么是事务二、为什么会出现事务三、事物的版本支持四、事物的提交方式五、事务常见的操作方式六、事务隔离级别如何理解隔离性1隔离级别查看与设置隔离性读未提交【Read Uncommitted】读提交【Read Committed】可重复读【Repeatable Read】串行化【serializa…

ChatGPT 联网和插件功能,下周起可直接使用,无需排队!

夕小瑶科技说 分享 来源 | 新智元 OpenAI和谷歌&#xff0c;已经打得急红了眼&#xff0c;ChatGPT Plus用户&#xff0c;下周就可以体验联网和插件功能&#xff0c;无需再排队。鲨疯了&#xff0c;真的鲨疯了&#xff01; ChatGPT&#xff0c;下周开始联网&#xff0c;并开放插…

DAY 57 MySQL数据库的事务

事务的概念 事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个 整体一起向系统提交或撤销操作请求&#xff0c;即这一组数据库命令要么都执行&#xff0c;要么都不执行。事务是一个不可分割的工作逻辑单元&#xff0c;在…

Python突破JS加密限制,进行逆向解密

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 目录标题 前言开发环境:模块使用:逆向目标逆向过程参数 JS 加密关键代码Python 登录关键代码尾语 &#x1f49d; 开发环境: Python 3.8 Pycharm 模块使用: time >>> 时间模块&#xff0c;属于内置&#xff0c;无…

lol由于找不到vcruntine140_1.dll文件,vcruntime140_1.dll修复方法

家人们有没有遇到过打开游戏或者软件提示由于找不到vcruntime140_1.dll&#xff0c;无法继续执行此代码的情况&#xff0c;是不是不知道怎么修复呢&#xff1f;Vcruntime140_1.dll是一个Windows系统文件&#xff0c;它是Microsoft Visual C Redistributable for Visual Studio …

快速搭建测ceph

一、cephadm介绍 Cephadm是一个由Ceph社区维护的工具&#xff0c;它用于在Ceph集群中管理和部署Ceph服务。它是一个基于容器化的工具&#xff0c;使用了容器技术来部署Ceph集群的不同组件。 使用Cephadm&#xff0c;管理员可以通过简单的命令行界面在整个Ceph集群中进行自动化…

Python递归树结构,回溯法深度优先、广度优先详解,代码实现

Python实现&#xff0c;递归算法&#xff0c;深度优先、广度优先 其实递归说白了就是循环本身函数&#xff0c;只不过下次循环的输入值是上次循环的结果值。关于递归算法&#xff0c;我经常把它用在搜索、计算中。我们来看一个简单的例子&#xff1a; 计算Demo 要实现1&…

高数杂项1

一些口诀 长杠变短杠&#xff0c;开口换方向 其实意思是底下这个 C ∩ D ‾ C ‾ ∪ D ‾ \overline{C \cap D} \overline C \cup \overline D C∩DC∪D 可导必可微&#xff0c;可微必可导 二者互为充要条件 可导必定连续&#xff0c;连续未必可导。连续必定可积,可微未必可积…

django-restful-framework基础知识

DRF 总体设计框架流程 DRF大体的工作流程如下图&#xff1a; 其中&#xff1a;这里的Request不再是Django默认的HttpRequest对象&#xff0c;而是REST Framework提供的扩展了HttpRequest类的Request类对象。 1. Web应用模式 在开发Web应用中&#xff0c;有两种应用模式&…

【sentinel】授权规则详解及源码分析

之前我们在配置流控规则时&#xff0c;可以根据origin参数来对调用方进行限流。 很多时候&#xff0c;我们需要根据调用方来限制资源是否通过&#xff0c;这时候可以使用Sentinel的黑白名单控制的功能&#xff0c;这就是授权规则。 黑白名单也是根据资源的请求来源&#xff0…

vite跨域问题,你可能需要看这篇文章

最近在学习项目的时候&#xff0c;使用了vite工具进行构建&#xff0c;然后出现了跨域的问题&#xff0c;中间的曲折不过多叙述&#xff0c;直接进入正题。 前端成功启动后的界面&#xff1a; 然后在后端进行的Controller上使用了如下的配置 然后浏览器就会出现跨域的问题 为什…

Maven 依赖管理 学习

目录 Maven 依赖管理 可传递性依赖发现 依赖范围 依赖管理 Maven 自动化部署 问题描述 解决方案 修改项目的 pom.xml Maven Release 插件 Maven Web 应用 创建 Web 应用 构建 Web 应用 部署 Web 应用 Maven 依赖管理 Maven 一个核心的特性就是依赖管理。当我们处…

【场景生成与研究】考虑时序相关性MC的场景生成与削减研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Docker基础篇(下)

1、容器命令 新建启动容器 docker run [OPTIONS] IMAGE [COMMAND] [ARG...]常用的参数&#xff1a; ● --name&#xff1a;为容器指定一个名称 ● -d&#xff1a;后台运行容器并返回容器ID&#xff0c;也即启动守护式容器 ● -i&#xff1a;以交互模式&#xff08;interacti…