哪些场景需要额外注意线程安全问题

今天我们主要学习哪些场景需要额外注意线程安全问题,在这里总结了四种场景。

访问共享变量或资源

第一种场景是访问共享变量或共享资源的时候,典型的场景有访问共享对象的属性,访问 static 静态变量,访问共享的缓存,等等。因为这些信息不仅会被一个线程访问到,还有可能被多个线程同时访问,那么就有可能在并发读写的情况下发生线程安全问题。比如我们上一课时讲过的多线程同时 i++ 的例子:

/**
 * 描述:     共享的变量或资源带来的线程安全问题
 */
public class ThreadNotSafe1 {

    static int i;

    public static void main(String[] args) throws InterruptedException {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < 10000; j++) {
                    i++;
                }
            }
        };
        Thread thread1 = new Thread(r);
        Thread thread2 = new Thread(r);
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(i);
    }
}

如代码所示,两个线程同时对 i 进行 i++ 操作,最后的输出可能是 15875 等小于20000的数,而不是我们期待的20000,这便是非常典型的共享变量带来的线程安全问题。

依赖时序的操作

第二个需要我们注意的场景是依赖时序的操作,如果我们操作的正确性是依赖时序的,而在多线程的情况下又不能保障执行的顺序和我们预想的一致,这个时候就会发生线程安全问题,如下面的代码所示:

if (map.containsKey(key)) {
    map.remove(obj)
}

代码中首先检查 map 中有没有 key 对应的元素,如果有则继续执行 remove 操作。此时,这个组合操作就是危险的,因为它是先检查后操作,而执行过程中可能会被打断。如果此时有两个线程同时进入 if() 语句,然后它们都检查到存在 key 对应的元素,于是都希望执行下面的 remove 操作,随后一个线程率先把 obj 给删除了,而另外一个线程它刚已经检查过存在 key 对应的元素,if 条件成立,所以它也会继续执行删除 obj 的操作,但实际上,集合中的 obj 已经被前面的线程删除了,这种情况下就可能导致线程安全问题。

类似的情况还有很多,比如我们先检查 x=1,如果 x=1 就修改 x 的值,代码如下所示:

if (x == 1) {
    x = 7 * x;
}

这样类似的场景都是同样的道理,“检查与执行”并非原子性操作,在中间可能被打断,而检查之后的结果也可能在执行时已经过期、无效,换句话说,获得正确结果取决于幸运的时序。这种情况下,我们就需要对它进行加锁等保护措施来保障操作的原子性。

不同数据之间存在绑定关系

第三种需要我们注意的线程安全场景是不同数据之间存在相互绑定关系的情况。有时候,我们的不同数据之间是成组出现的,存在着相互对应或绑定的关系,最典型的就是 IP 和端口号。有时候我们更换了 IP,往往需要同时更换端口号,如果没有把这两个操作绑定在一起,就有可能出现单独更换了 IP 或端口号的情况,而此时信息如果已经对外发布,信息获取方就有可能获取一个错误的 IP 与端口绑定情况,这时就发生了线程安全问题。在这种情况下,我们也同样需要保障操作的原子性。

对方没有声明自己是线程安全的

第四种值得注意的场景是在我们使用其他类时,如果对方没有声明自己是线程安全的,那么这种情况下对其他类进行多线程的并发操作,就有可能会发生线程安全问题。举个例子,比如说我们定义了 ArrayList,它本身并不是线程安全的,如果此时多个线程同时对 ArrayList 进行并发读/写,那么就有可能会产生线程安全问题,造成数据出错,而这个责任并不在 ArrayList,因为它本身并不是并发安全的,正如源码注释所写的:

Note that this implementation is not synchronized. If multiple threads
access an ArrayList instance concurrently, and at least one of the threads
modifies the list structurally, it must be synchronized externally.

这段话的意思是说,如果我们把 ArrayList 用在了多线程的场景,需要在外部手动用 synchronized 等方式保证并发安全。

所以 ArrayList 默认不适合并发读写,是我们错误地使用了它,导致了线程安全问题。所以,我们在使用其他类时如果会涉及并发场景,那么一定要首先确认清楚,对方是否支持并发操作,以上就是四种需要我们额外注意线程安全问题的场景,分别是访问共享变量或资源,依赖时序的操作,不同数据之间存在绑定关系,以及对方没有声明自己是线程安全的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫网易云音乐,Tkinter制作音乐播放器

目录 一、效果展示 二、环境 三、实现过程 四、源码 一、效果展示 页面的美化以及功能还有待升级~ 先来说一下已有功能吧&#xff1a; 可以在搜索框中通过歌曲或歌手名称进行搜索&#xff0c;效果和在网易云官网搜索一样。 点击开始下载&#xff0c;就会将搜索结果的第一…

安装python虚拟环境

什么是虚拟环境&#xff1a; 虚拟环境的意义&#xff0c;就如同 虚拟机 一样&#xff0c;它可以实现不同环境中Python依赖包相互独立&#xff0c;互不干扰。 环境准备 安装python &#xff08;到官网下载Download Python​配置环境变量&#xff0c;cmd进入命令行输入 python…

Flutter——最详细(Scaffold)使用教程

Scaffold简介 相当于界面的主体&#xff08;类似于安卓最外层PhoneWindow&#xff09;&#xff0c;组件的展示都必须依附于它。 使用场景&#xff1a; 每一个界面都是脚手架&#xff0c;通过它来进行架构实现&#xff0c;优美的布局效果。 属性作用appBar顶部的标题栏body显示整…

磁盘监控:告警时发送邮件

1.配置邮箱 1.编辑邮箱配置文件 vim /etc/mail.rc2.在末尾输入自己的邮箱配置&#xff0c;以163邮箱为例 #开启ssl set ssl-verifyignore #证书目录&#xff0c;下方为centos系统证书默认位置&#xff0c;也自行生成证书并指定 set nss-config-dir/etc/pki/nssdb # 配置的第…

一文知晓Linux文件权限

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f…

聚量推客滴滴学生认证app地推网推拉新升级啦

“聚量推客”滴滴学生认证项目升级 滴滴学生认证升级后分为微信推广版本和支付宝推广版本两种码 根据自己需要选择推广场景&#xff0c;适合地推和网推

CSRF跨域请求伪造

1.SSRF服务端请求伪造&#xff08;外网访问内网&#xff09; SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下&#xff0c;SSRF是要目标网站的内部系统。&#xff08;因为他是从内部系统访问的&#xf…

甲骨文真的要开放Java EE?

甲骨文表示&#xff0c;目前正在与可能的几个候选基金会&#xff0c;以及许可证持有者和社区在进行谈判。随着Java EE 8平台的确定&#xff0c;甲骨文在周四表示&#xff0c;目前正在考虑将Java Enterprise Edition技术转移到开源社区。 甲骨文在其博客中说道&#xff0c;这次的…

【TES641】基于VU13P FPGA的4路FMC接口基带信号处理平台

板卡概述 TES641是一款基于Virtex UltraScale系列FPGA的高性能4路FMC接口基带信号处理平台&#xff0c;该平台采用1片Xilinx的Virtex UltraScale系列FPGA XCVU13P作为信号实时处理单元&#xff0c;该板卡具有4个FMC子卡接口&#xff08;其中有2个为FMC接口&#xff09;&#x…

【App 抓包提示网络异常怎么破?】

背景 当你测试App的时候,想要通过Fiddler/Charles等工具抓包看下https请求的数据情况,发现大部分的App都提示网络异常/无数据等等信息。以“贝壳找房”为例: 455 x 705 Fiddler中看到的请求是这样的: 619 x 215 你可能开始找证书的问题:是不是Fiddler/Charles的证书没有…

解决提交到App Store时的ITMS-90478和ITMS-90062错误

解决提交到App Store时的ITMS-90478和ITMS-90062错误 目录 引言 正文 1. 什么是ITMS-90478和ITMS-90062错误&#xff1f; 2. 解决方法 2.1 确定当前的版本号和构建号 2.2 递增版本号和构建号 2.3 再次尝试提交应用 总结 参考资料 错误记录 摘要&#xff1a;本文为iOS…

基于Java的宠物商店管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

高校打造动捕实训室:开启元宇宙创新教育时代

随着科技的发展&#xff0c;高校教育面临着新的挑战与机遇。高校动捕实训室涉及多个学科领域&#xff0c;如艺术学院、设计学院、新媒体学院等&#xff0c;适用于动画、视觉传达、数码媒体、数字媒体艺术等专业。动捕实训室可以为学生提供创意发挥的空间&#xff0c;使用动捕设…

【Airflow】构建爬虫任务系统

爬虫脚本太多了需要进行管理一下&#xff0c;领导决定使用airflow 我了解了一下这个平台是用来做任务调度。 是一个ETL工具 ETL是将业务系统的数据经过抽取、清洗转换之后加载到数据仓库的过程 这里是一个github的地址 https://github.com/apache/airflow 这里是官方文档 http…

使用AOP切面实现日志记录功能

系列文章 1.SpringBoot整合RabbitMQ并实现消息发送与接收 2. 解析JSON格式参数 & 修改对象的key 3. VUE整合Echarts实现简单的数据可视化 4. Java中运用BigDecimal对字符串的数值进行加减乘除等操作 5. List&#xff1c;HashMap&#xff1c;String,String&#xff1e;&…

seacms_CNVD-2020-22721_v10.1漏洞分析与复现

seacms 远程命令执行漏洞复现 文章目录 seacms 远程命令执行漏洞复现一、基本信息二、组件简介三、漏洞详情漏洞介绍影响范围危害 四、防御1. 漏洞存在性检测2. 修复建议3. 规避措施4. 漏洞利用检测 五、漏洞复现1. 复现环境2. 漏洞复现 一、基本信息 titlecontentnote漏洞编号…

【Redis】Docker部署Redis数据库

Docker部署Redis数据库 1. Redis介绍2. CentOS 7 安装 & Docker 配置3. 拉取Redis 镜像、创建容器3.1 配置Docker镜像源3.2 拉取Redis 镜像3.3 容器创建 1. Redis介绍 Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的使用…

二、【常用的几种抠图方式一】

文章目录 选框抠图快速选择工具抠图魔棒工具抠图对象选择工具抠图套索工具抠图多边形套索工具抠图磁性套索工具抠图 选框抠图 选框工具抠图适合规则的图形&#xff0c;如下图先使用选框工具框出对象的图轮廓&#xff0c;然后再选择并遮住在里边擦出图形的边缘&#xff0c;根据…

【LeetCode:1465. 切割后面积最大的蛋糕 | 贪心 + 排序】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

安全和便捷:如何将运营商二要素API应用于实名制管理中

引言 随着互联网的快速发展&#xff0c;数字化身份验证和实名制管理变得越来越重要。在金融、电子商务、社交媒体等领域&#xff0c;确保用户身份的安全和准确性至关重要。运营商二要素核验API成为了实名制管理的有力工具&#xff0c;它不仅能够提供高水平的安全性&#xff0c…