当前位置: 首页 > news >正文

[JAVAEE] 线程安全问题

目录

一. 什么是线程安全

二. 线程安全问题产生的原因

三. 线程安全问题的解决

3.1 解决修改操作不是原子性的问题 => 加锁

a. 什么是锁

b.  没有加锁时

c. 加锁时 

d. 死锁

e. 避免死锁 

3.2 解决内存可见性的问题 => volatile关键字 (易变的, 善变的)

a. 不加volatile关键字

b. 加volatile关键字


一. 什么是线程安全

在多线程并发执行的过程中, 出现 bug, 称为线程不安全. 反之则线程安全.


二. 线程安全问题产生的原因

1. 操作系统对于线程的调度是随机的, 抢占式的[根本原因].

2. 多个线程修改同一个变量.

3. 修改操作不是原子的. => 解决: 锁

4. 内存可见性. => 解决: volatile(adj. 善变的. 易变的)关键字

5. 执行重排序. => 解决: wait() 与 notify() 等待 与 通知


三. 线程安全问题的解决

3.1 解决修改操作不是原子性的问题 => 加锁

a. 什么是锁

synchronized修饰普通方法, 是对this加锁.

synchronized修饰静态方法, 是对类对象加锁. 

b.  没有加锁时

没有对count++操作进行加锁时, count的结果总是 <= 100000, 这是因为(线程调度是随机的, 抢占式的 + count++操作不是原子的)

c. 加锁时 

对count++操作进行加锁后, count++操作可以认为变成原子的了, 这时, count的最终结果就符合预期.

d. 死锁

构成死锁的场景:

1. 一个线程, 一把锁 (但是, java中锁具有可重入特性, 此种情况下, 并不会构成死锁)

2. 两个线程, 两把锁

3. n个线程, m把锁 

构成死锁的四个必要条件:

1. 锁是互斥的. (线程1获取了锁1, 这时线程2想要再获取锁1 就要阻塞等待)

2. 锁是不可抢占的

3. 请求和保持. (线程1获取了锁1, 线程2获取了锁2, 此时, 线程1想要再获取锁2, 线程2想要再获取锁1, 这时就会构成死锁, 线程阻塞) => 解决: 一定情况下, 避免嵌套

4. 循环等待. => 解决: 约定加锁的顺序.

e. 避免死锁 

想要避免死锁, 就要解决 3 或者 4 这两个必要条件.

解决3. (避免嵌套)

解决4.(按照一定的顺序进行加锁)

3.2 解决内存可见性的问题 => volatile关键字 (易变的, 善变的)

a. 不加volatile关键字

 

可以观察到, t1线程并没有因为t2线程输入val的值不是0而结束, 反而一直在RUNNABLE(运行中). 这是因为, jvm对代码进行了优化, jvm检测到val的值一直不发生改变, 为了提高效率, 就把val转移到了寄存器中, 此时t2线程输入val还在和内存进行交互, 并不会改变val的值.

b. 加volatile关键字

加上volatile关键字, 表示val的值是易变的, 用户随时可能会修改, 此时, jvm就不会对val的操作进行优化, val一直存在于内存中.

未完成... 

http://www.lryc.cn/news/461810.html

相关文章:

  • k8s 集群给用户生成 kubeconfig 文件
  • (八)Proteus仿真STM32单片机GPIO驱动数码管
  • Python进阶知识1
  • 单片机设计|基于STM32实现具有室内定位功能的智能手环的设计
  • 计算机网络——运输层(可靠传输、超时重传、选择确认、流量控制和拥塞控制、TCP连接和释放)
  • Web安全实践
  • 【算法篇】动态规划类(2)——01背包+完全背包(笔记)
  • 基于SpringBoot的“社区医院管理服务系统”的设计与实现(源码+数据库+文档+PPT)
  • 二进制漏洞利用 | 整数溢出探究
  • 10种经典的螺栓防松设计
  • 开放式蓝牙耳机哪个品牌好用?开放式耳机排行榜测评!
  • 新能源行业必会基础知识---电力现货问答---第5问---何为电力中长期市场?与电力现货市场之间有何关系?国内试点地区如何衔接?国外有哪些经验值得借鉴?
  • 如何将数据从 AWS S3 导入到 Elastic Cloud - 第 2 部分:Elastic Agent
  • DTL698电表数据 转 profinet IO协议项目案例
  • CSS @规则(At-rules)系列详解___@font-face规则使用方法
  • 如何通过CDN优化网站服务器访问速度?
  • JAVA学习-练习试用Java实现“自定义函数之字符反转”
  • 大衍数列——考研408考试科目之数据算法——未来之窗学习通
  • JVM(HotSpot):直接内存及其使用建议
  • centos7安装mysql5.7
  • 如何在JVS逻辑引擎中巧妙运用包含查询功能?
  • Spring Boot视频网站:安全与可扩展性设计
  • 深入理解 Flutter 鸿蒙版的 Stack 布局:适配屏幕与层叠样式布局
  • JavaScript中Number相关特性
  • Redis中String类型数据扩容原理分析
  • 智能码二维码zhinengma.cn在供应链管理中有哪些优势?
  • 代理商培训新策略:利用内部知识库提升培训效果
  • Redis 哨兵模式下DB库操作审计
  • latex公式输入-矩阵
  • NSSCTF-WEB-easy_eval