【JavaEE】多线程进阶(一)饿汉模式和懒汉模式

多线程进阶(一)

文章目录

  • 多线程进阶(一)
    • 单例模式
      • 饿汉模式
      • 懒汉模式

本篇主要引入多线程进阶的单例模式,为后面的大冰山做铺垫

代码案例介绍

单例模式

非常经典的设计模式

啥是设计模式

设计模式好比象棋中的 “棋谱”. 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏.

软件开发中也有很多常见的 “问题场景”. 针对这些问题场景, 大佬们总结出了一些固定的套路. 按照这个套路来实现代码, 也不会吃亏.

单例 -> 单个实例(对象)

在有些场景下,希望有的类,只能有一个对象,不能有多个!在这样的场景下就可以使用单例模式了。

举个有意思的例子就是,你只能娶一个老婆,不过你可以生很多娃🥵🥵🥵,娃就不一定是单例的


在代码中,有很多用于管理数据的对象,就应该是”单例“的,例如mysql JDBC DataSource(描述mysql服务器的位置)

那么这里有个问题:

单例这个事情,还需要设计模式吗?

当我们写代码的时候,只给这个类new一次对象,不去new多次不就行了?

实际上,设计模式是非常必要的,这其实上是属于设计模式,这完全就是取决于程序员的编程素养。

不过俗话说,宁可相信世界上有鬼,也不能相信人的这张破嘴!人是非常不靠谱的。

这样的思想方法在很多地方都会涉及到:

  1. final
  2. intreface
  3. @Override
  4. throws

于是此时就需要让编译器帮我们做监督,确保这个对象不会出现多个new(出现多个的时候就直接编译报错)

饿汉模式

类加载的同时, 创建实例.

// 饿汉模式
class Singleton{private static Singleton instance = new Singleton();//通过这个方法来获取到刚才的实例//后续如果想使用这个类的实例,都通过 getInstance 方法来获取public static Singleton getInstance(){return instance;}//把构造方法设置为私有,此时类外面的其他代码,就无法 new 出这个类的对象private Singleton(){}
}public class Demo21 {public static void main(String[] args) {//此外又有一个实例,这就不是单例了//Singleton s1 = new Singleton();Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println(s1 == s2);//true}
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

懒汉模式

相比于饿汉模式,他就比较从容,在第一次使用的时候,再去创建实例

//懒汉模式class SingletonLazy{private static volatile SingletonLazy instance = null;public static SingletonLazy getInstance(){if (instance == null) {if (instance == null) {instance = new SingletonLazy();}}return instance;}private SingletonLazy(){}
}public class Demo22 {public static void main(String[] args) {//此外又有一个实例,这就不是单例了//Singleton s1 = new Singleton();SingletonLazy s1 = SingletonLazy.getInstance();SingletonLazy s2 = SingletonLazy.getInstance();System.out.println(s1 == s2);//true}
}

在这里插入图片描述

我们举个例子:

文本编辑器

记事本

需要打开一个非常大的文件

  1. 先把所有的内容都加载到内存中,然后再显示内容(加载过程会很慢)
  2. 只加载一小部分数据到内存,立即显示内容,随着用户翻页,再动态加载其他内容(懒汉模式

那么这里我们抛出一个问题:

以上两种模式的写法,是否是线程安全的?(如果有多个线程,同时调用getInstance,是否会出问题?)

如果多个线程,同时修改同一个变量,此时就可能出现线程安全问题

如果多个线程,同时读取同一个变量,这个时候就没什么事情,不会有安全问题

那么我们看看饿汉模式的代码:

public static Singleton getInstance(){return instance;}

饿汉模式下的getInstance只是进行读取,不是修改,那么他也就没有线程安全的问题了~

那我们看看懒汉模式的代码:

if(instance == null){instance = new SingletonLazy();
}
return instance;

它既会读取,又会修改,就可能存在问题~

在这里插入图片描述

那么我们怎么保证懒汉模式是线程安全的呢?

类似于下面这种改法吗?

public static SingletonLazy getInstance(){if (instance == null) {synchronized (SingletonLazy.class) {if (instance == null) {instance = new SingletonLazy();}}}return instance;}

当然不是,我们要明确一个事情,就是:锁,不是加了就安全

加的位置对不对,才是关键

  1. 锁的{}的范围,是合理的,能够把需要作为整体的每个部分都囊括进去
  2. 锁的对象,也得是能够起到合理的锁竞争的效果

这样才是真正的加锁

所以修改如下:

public static SingletonLazy getInstance(){synchronized (SingletonLazy.class) {if (instance == null) {if (instance == null) {instance = new SingletonLazy();}}}return instance;}

ifnew合并成一个整体,此时的线程安全就迎刃而解了

不过一旦这么写的话,后续每次调用getInstance,都需要先加锁了

不过这种操作属实是画蛇添足了,加锁是一个开销很大的操作,加锁就可能会涉及到锁冲突 一冲突就会引起阻塞等待。

还有就是:一旦某个代码涉及到 加锁,那么基本上就可以宣告这个代码和“高性能”无缘了~

但是实际上,懒汉模式,线程安全的问题,只是出现在最开始的时候(对象还没开始new呢)

一旦对象new出来了,后续多线程调用getInstance,就只有读操作,就不会线程不安全了~

那么这里抛出一个问题:

是否有什么办法可以让代码线程安全,又不会对执行效率产生太多影响呢?

欲知后事如何,敬请期待下一篇博客~

主要是我临时有事,等明天写完再更😥😥😥😥😥😥😥😥😥

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python无废话-办公自动化Excel格式美化

设置字体 在使用openpyxl 处理excel 设置格式,需要导入Font类,设置Font初始化参数,常见参数如下: 关键字参数 数据类型 描述 name 字符串 字体名称,如Calibri或Times New Roman size 整型 大小点数 bold …

做外贸独立站选Shopify还是WordPress?

现在确实会有很多新人想做独立站,毕竟跨境电商平台内卷严重,平台规则限制不断升级,脱离平台“绑架”布局独立站,才能获得更多流量、订单、塑造品牌价值。然而,在选择建立外贸独立站的过程中,选择适合的建站…

TinyWebServer整体流程

从main主函数开始: 一、定义MySQL数据库的账号、密码和用到的数据库名称。 二、调用Config获得服务器初始化属性 在这一步确定触发模式端口等信息。 三、创建服务器实例对象 设置根目录、开辟存放http连接对象的空间,开辟定时器空间。 四、利用Confi…

《视觉 SLAM 十四讲》V2 第 5 讲 相机与图像

文章目录 相机 内参 && 外参5.1.2 畸变模型单目相机的成像过程5.1.3 双目相机模型5.1.4 RGB-D 相机模型 实践5.3.1 OpenCV 基础操作 【Code】OpenCV版本查看 5.3.2 图像去畸变 【Code】5.4.1 双目视觉 视差图 点云 【Code】5.4.2 RGB-D 点云 拼合成 地图【Code】 习题题…

Clion中使用C/C++开发stm32程序

前言 从刚开始学习阶段,一直是用的keil5开发stm32程序,自从看到稚晖君推荐的CLion开发嵌入式程序后,这次尝试在CLion上开发stm32程序。 1、配置CLion用于STM32开发的环境 这里我就不详细写了,没必要重新写,网上教程很多…

Http常见问题

说说 HTTP 常用的状态码及其含义? HTTP 状态码首先应该知道个大概的分类: 1XX:信息性状态码2XX:成功状态码3XX:重定向状态码4XX:客户端错误状态码5XX:服务端错误状态码 301:永久性…

突破封锁|华为芯片10年进化史:从K3V1到麒麟9000S

华为海思麒麟芯片过去10年研发历程回顾如下: 2009年:华为推出第一款手机芯片K3V1,采用65nm工艺制程,基于ARM11架构,主频600MHz,支持WCDMA/GSM双模网络。这款芯片搭载在华为U8800手机上,标志着华…

伟大不能被计划

假期清理书单,把这个书读完了,结果发现出奇的好,可以说是值得亲身去读的书,中间的一些论述提供了人工智能专业方面的视角来论证这这个通识观点,可信度很不错; 这篇blog也不是对书的总结,更多的是…

CSS小计

1:设置图片随窗缩放 使用百分比 width: 100%;height: 100%; 使用vmin: 将可视区域分为100vmin width: 100vmin;height: 100vmin; 2:设置字体颜色与背景色融合 mix-blend-mode: difference 3: 设置宽度自适应 width:fit-content 4:外边距合并 当两个相领的两个容…

Spring Cloud OpenFeign 性能优化的4个方法

OpenFeign 是 Spring 官方推出的一种声明式服务调用和负载均衡组件。它的出现就是为了替代已经进入停更维护状态的 Netflix Feign,是目前微服务间请求的常用通讯组件。 1.超时设置 OpenFeign 底层依赖Ribbon 框架,并且使用了 Ribbon 的请求连接超时时间…

【数据结构】排序

🐇 🔥博客主页: 云曦 📋系列专栏:数据结构 💨吾生也有涯,而知也无涯 💛 感谢大家👍点赞 😋关注📝评论 文章目录 前言一、排序的概念及运用二、常…

Swift SwiftUI CoreData 过滤数据 1

Xcode: Version 14.3.1 (14E300c) iOS: 16 预览&#xff1a; Code: import SwiftUI import CoreDatastruct TodosSearch: View {State private var search_title "测试"FetchRequest var todos_search: FetchedResults<Todo>init() {let request: NSFetchReq…