【共享模型-----管程】

news2024/12/24 10:18:38

文章目录

  • 1. 为什么会出现线程安全问题
  • 2. synchronized 解决方案
    • 2.1 线程八锁
  • 3. `变量`的线程安全分析
    • 3.1 局部变量线程安全分析
    • 3.2 常见线程安全类

1. 为什么会出现线程安全问题

一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区

共享资源:

  • 多个线程读共享资源其实也没有问题
  • 在多个线程对共享资源读写操作时发生指令交错,就会出现问题

2. synchronized 解决方案

为了避免临界区的竞态条件发生,有多种手段可以达到目的:

  • 阻塞式的解决方案:synchronized,Lock
  • 非阻塞式的解决方案:原子变量

synchronized,俗称的【对象锁】,它采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】,其它线程再想获取这个【对象锁】时就会阻塞住。这样就能保证拥有锁
的线程可以安全的执行临界区内的代码,不用担心线程上下文切换

如果多个线程要实现对共享资源的访问,用synchronized锁对这个资源的操作,synchronized 必须锁同一个对象或者同一个类。

2.1 线程八锁

在这里插入图片描述

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

3. 变量的线程安全分析

成员变量静态变量是否线程安全?

  • 如果它们没有共享,则线程安全
  • 如果它们被共享了,根据它们的状态是否能够改变,又分两种情况
    • 如果只有操作,则线程安全
    • 如果有读写操作,则这段代码是临界区,需要考虑线程安全

局部变量是否线程安全?

  • 局部变量是线程安全的
  • 但局部变量引用的对象则未必
    • 如果该对象没有逃离方法的作用范围,它是线程安全的
    • 如果该对象逃离方法的作用范围,需要考虑线程安全

3.1 局部变量线程安全分析

变量有两种类型,值引用和对象引用。
1. 值引用
在这里插入图片描述
每个线程调用 test1() 方法时局部变量 i,会在每个线程的栈帧内存中被创建多份,因此不存在共享
在这里插入图片描述

2. 对象引用:list在本案例中不是局部变量,而是全局共享的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
分析:

  • 无论哪个线程中的 method2 和method3 引用的都是同一个对象中的 list ,多个线程访问共享变量又有读和写操作会出现线程安全问题。

在这里插入图片描述

解决线程安全问题:将 list 修改为局部变量
在这里插入图片描述
在这里插入图片描述

思考:为 ThreadSafe 类添加子类,当 method2 或 method3 方法用public修饰,会不会出现线程安全问题呢?:会
在这里插入图片描述
在这里插入图片描述

上面图片为正确的写法不会出现线程安全问题,但是当我们将method2和method3方法用public修饰的话,那么当一个子类继承时如果重写了method2和method3,也有可能导致线程安全的问题,比如重写方法中又开了一个线程然后对同一个共享资源进行操作,这时旧线程和这个新线程就会因为对同一个共享资源进行操作而产生线程安全问题。(但是用private修饰则不会重写,不会覆盖父类中的方法,这时是子类定义的一个新的方法)所以用private修饰,final修饰也是防止公共方法避免受到子类的影响(避免子类重写覆盖)。 private 或 final 提供【安全】的意义,开闭原则中的闭。

3.2 常见线程安全类

  • String
  • Integer
  • StringBuffer
  • Random
  • Vector
  • Hashtable
  • java.util.concurrent 包下的类(JUC)

这里说它们是线程安全的是指,多个线程调用它们同一个实例的某个方法时,是线程安全的。
比如下面的例子线程安全:
在这里插入图片描述
==但是:==单个方法线程安全,但是组合不安全,原因是Hashtable()中的get和put方法都用了synchronized修饰,但只能保证get操作的原子性或者put方法的原子性,但是不同的针对不同的对象,synchronized只能约束同一个,导致线程安全问题。
在这里插入图片描述
在这里插入图片描述

不可变类线程安全性
String、Integer 等都是不可变类,因为其内部的状态不可以改变,因此它们的方法都是线程安全的:只能读不能改,改的话都是创建一个新的对象,包含了改后的值。

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

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

相关文章

一张图看懂 8 种网络协议

什么是网络协议? 网络协议就是计算机之间沟通的语言,为了有效地交流,计算机之间需要一种共同的规则或协议,就像我们和老外沟通之前,要先商量好用哪种语言,要么大家都说中文,要么大家都说英语&a…

优思学院|六西格玛将烹饪和美味提升至极致

最近,我们曾提到一个美国男子如何利用六西格玛来控制糖尿病。这表明六西格玛逐渐被认为是一个不仅可以在工作场所之外使用,尤其不仅限于制造业的系统。 六西格玛的核心理念是改进过程的质量,从而改善最终结果。如果你做了晚餐或尝试了一道新…

ESP32设备驱动-OLED显示BME280传感器数据

OLED显示BME280传感器数据 文章目录 OLED显示BME280传感器数据1、BME280介绍2、硬件准备3、软件准备4、代码实现在本文中,我们将介绍如何使用OLED显示BME280传感器的数据。 1、BME280介绍 BME280 传感器用于测量有关环境温度、大气压力和相对湿度的读数。 它主要用于以低功耗…

2023/10/4 -- ARM

今日任务:QT实现TCP服务器客户端搭建的代码,现象 ser: #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);server new QTcpSe…

JMeter性能分析实战一:日常登录接口

负载测试 日常需求:负载测试! 对于桥的负载测试:我给你20t的一排车辆,看你能不能撑得住20t! 对于系统的负载测试: 逐步增加负载,便于问题的发现和定位,不要操之过急。逐步增加负载…

由Long类型引发的生产事故

事情原由 今天测试忽然在群里发了一个看似非常简单的线上问题,具体是:在后台通过订单编号(orderId)修改订单信息时,修改不成功 ,修改前后的订单数据完全没有发生变化。第一眼看到这个问题的时候,我心想后台实现逻辑并不…

CSS 语法

CSS 实例 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明: 选择器通常是您需要改变样式的 HTML 元素。 每条声明由一个属性和一个值组成。 属性(property)是您希望设置的样式属性(style attribute&#x…

监狱劳动工具管理系统|智工具DW-S308的功能

监狱劳动工具管理系统(智工具DW-S308)是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对工具进行统一管理、分析的信息化、智能化、规范化的系统。 目前监狱的劳动工具管理很多还停留在固定工位,人盯人、人管人等落后的管理模式&#xff…

图谱滤波(Graph Spectral Processing)-1

时域和空域信号的滤波是图像处理的基本技术之一,迄今已得到广泛的研究。Graph Spectral Processing(GSP)可以处理不规则结构的信号,这些信号在数学上用图形表示。利用谱图理论研究了图信号滤波的理论和方法。在图像处理中,图是表示像素形成的…

华为云云耀云服务器L实例评测|RabbitMQ的Docker版本安装 + 延迟插件安装 QQ邮箱和阿里云短信验证码的主题模式发送

前言 最近华为云云耀云服务器L实例上新,也搞了一台来玩,期间遇到各种问题,在解决问题的过程中学到不少和运维相关的知识。 本篇博客介绍RabbitMQ的Docker版本安装和配置,延迟插件的安装;结合QQ邮箱和阿里云短信验证码…

Gurobi设置初始可行解

目录 1. 决策变量的Start属性直接设置变量的初始值 1.1 Start:MIP变量的起始值(初值)double类型,可更改 1.2 StartNodeLimit:限制了在完善一组输入部分变量的初始解时,MIP所探索的分支定界的节点的数量 …

SAAS软件营销——利用人工智能帮助企业了解客户

软件营销部队(Salesforce)是全球领先的客户关系管理(CRM)解决方案供应商之一,其产品和服务旨在帮助企业成长,并追踪与客户的关系。 在1999 年成立时,它就率先提出了通过互联网(现在通常称为“云”)实现“软件即服务”(SaaS)的概念。 SaaS提…

周期性触发的自定义触发器

背景 本文我们实现一个周期性触发的自定义触发器,顺便看下实现自定义触发器的一些要点 周期性触发器实现 实现一个每分钟触发一次的自定义事件时间触发器,实现代码和注意事项如下所示 package wikiedits.trigger;import org.apache.flink.api.common…

线程通信初始

简单认识一下线程通信 目录 简单认识一下线程通信线程通信定义线程通信模型之一释疑示例案例案例要求案例简单实现 拓展等待和唤醒API 参考视频 注:线程通信 前提是 线程安全 线程通信定义 当多个线程共同操作共享的资源时,线程间通过某种方式互相告知自…

【算法训练-二分查找 三】【特殊二分】寻找峰值

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【数组的二分查找】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为…

Vue3+TS+ECharts5实现中国地图数据信息显示

1.引言 最近在做一个管理系统,主要技术栈使用的是Vue3TSViteElementPlus,主要参考项目是yudao-ui-admin-vue3,其中用到ECharts5做数字大屏,展示中国地图相关信息,以此基础做一个分享,写下这篇文章。 &quo…

解决ASP.NET Core的中间件无法读取Response.Body的问题

概要 本文主要介绍如何在ASP.NET Core的中间件中,读取Response.Body的方法,以便于我们实现更多的定制化开发。本文介绍的方法适用于.Net 3.1 和 .Net 6。 代码和实现 现象解释 首先我们尝试在自定义中间件中直接读取Response.Body,代码如…

Appleid苹果账号自动解锁改密(自动解锁二验改密码)

目前该项目能实现以下功能: 多用户使用,权限控制多账号管理账号分享页,支持设置密码、有效期、自定义HTML内容自动解锁与关闭二步验证自动/定时修改密码自动删除Apple ID中的设备代理池与Selenium集群,提高解锁成功率允许手动触发…

先输入列,再输入行

想要的表格行数和列数是 5 行 5 列,以下是相应的代码实现: # 定义表格行数和列数 rows 5 cols 5# 创建一个二维列表作为表格 table [[ for j in range(cols)] for i in range(rows)]print("请输入表格数据:")while True:# 获取…

Python无废话-办公自动化Excel读取操作

openpyxl模块介绍 openpyxl是一个用于处理Excel文件的Python库,用于读取/写入Excel2010 xlsx/xlsm/xltx/xltm文件(不支持xls格式)。通过使用openpyxl库,可 以轻松地在Python程序中实现对Excel文件的操作。 openpyxl 安装 方式1:使用pip 命令安装&…