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

【Java】保证并发安全的三大特性

一、并发编程三大特性的定义和由来

并发编程这三大特性就是为了在多个线程交替执行任务的过程中保证线程安全性。

二、为什么会出现线程不安全的现象呢?

接下来我们从这三个特性切入来介绍线程不安全的原因。

1.原子性:

一组操作要么全部执行,要么全部不执行,执行过程中不能被中断。

Java并发编程中必然存在多个线程的交替执行,因此不论采取何种线程调度算法,都会涉及到线程的切换,而在线程切换的过程中,如果对某个共享变量的操作不是原子的,就可能会导致脏读等各种数据混乱的问题,造成线程不安全,因此我们必须保证对共享变量操作的原子性防止数据混乱以保证线程安全。

如何保证原子性:

通过 synchronized 关键字保证原子性。
通过 Lock保证原子性。
通过 CAS保证原子性。

2.可见性:

一个线程修改了某个共享变量,其他线程立即可以“感知到”。

从对Java内存模型的了解我们可以知道,Java中每个线程对共享数据的修改都是在其工作内存中进行的,而每个线程在其工作内存中对共享数据的修改并不会立即同步到主内存,因此其他线程并不能立即“感知到”某个线程对共享数据的修改,这样就会导致每个线程工作内存中同一个共享变量的值不一定相等,即缓存不一致,导致线程不安全。因此我们必须保证可见性以保证线程安全。

如何保证可见性:

通过 volatile 关键字保证可见性。
通过 内存屏障保证可见性。
通过 synchronized 关键字保证可见性。
通过Lock保证可见性。
通过 final 关键字保证可见性

3.有序性:

如果在本线程内观察,所有操作都是有序的;如果在一个线程中观察另一个线程,所有的操作都是无序的。

程序执行的顺序按照代码的先后顺序执行。JVM 存在指令重排,所以存在有序性问题。

为了提高性能,编译器和处理器可能会在满足数据依赖性的条件下对操作进行重新排序,即在单线程环境中,对指令的重排序并不影响执行结果,在单线程环境下,这种重排序不会有什么问题,因为执行结果总是正确的,但是在多线程环境下就会出现问题。

a+=1;a*=2这两个操作不能交换顺序,一旦交换会影响程序的执行结果。

如何保证有序性:

通过 volatile 关键字保证有序性。
通过 内存屏障保证有序性。
通过 synchronized关键字保证有序性。
通过Lock保证有序性。

三、总结一下

之所以会出现并发编程的三大特性,就是因为在提升程序性能的同时需要保证安全性,而原子性、可见性、有序性这三大特性可以认为是线程安全的等价概念,我们需要通过一些机制来保证这三大特性,也就是保证线程安全。

原子性:一次或多次操作在执行期间不被其他线程影响

可见性:当一个线程在工作内存修改了变量,其他线程能立刻知道

有序性JVM对指令的优化会让指令执行顺序改变,有序性是禁止指令重排

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

相关文章:

  • 如何优雅的用golang封装配置项(Functional Options)
  • Springboot 使用thymeleaf 服务器无法加载resources中的静态资源异常处理
  • 服务端IOS订阅类型支付接入详细说明与注意事项
  • 【剑指Offer】重建二叉树(递归+迭代)
  • 注解@Transactional 原理和常见的坑
  • 2023年全国最新交安安全员精选真题及答案4
  • 扬帆优配|半天翻倍,“蹭热点”翻车,前期“牛股”已近腰斩
  • 6 种易于上手的编程副业,每月赚取 1,000 多美元——没有废话
  • 第九届蓝桥杯省赛 C++ B组 - 日志统计
  • 记一次服务器入侵事件的应急响应
  • 作用域链查找机制(回顾)
  • 前端基础之HTML扫盲
  • 大规模食品图像识别:T-PAMI 2023论文解读
  • 【java】Spring Cloud --Spring Cloud Alibaba RocketMq 异步通信实现
  • 玫瑰花变蚊子血,自动化无痕浏览器对比测试,新贵PlayWright Vs 老牌Selenium,基于Python3.10
  • Spring Cloud入门篇 Hello World | Spring Cloud 1
  • C++学习笔记-数据结构
  • 【C++的OpenCV】第五课-OpenCV图像常用操作(二):OpenCV的基本绘图、平滑滤波(模糊)处理
  • [SSD固态硬盘技术 19] 谁是数据的守护神? 盘内RAID1/RAID5图文详解_盘内数据冗余保护
  • linux相对于windows环境为啥相对来说更加具有安全性
  • iOS开发笔记之九十七——关于Restful API的一些总结
  • Linux系统Nginx下载和安装
  • 交叉编译 acl
  • wait/notify方法 等待唤醒机制
  • c++笔记之构造函数中的default作用
  • 【代码随想录二刷】Day24-回溯-C++
  • Kubernetes中YAML 文件简介
  • 骨传导耳机是怎么发声的,骨传导耳机值得入手嘛
  • 会声会影2023官方新功能介绍
  • vue:pdf.js使用细节/隐藏按钮/设置、获取当前页码/记录阅读进度/切换语言(国际化)