6、原子性、可见性和有序性以及原因

本文详细介绍了Java并发中的三大性质——原子性、可见性和有序性。原子性通过lock和unlock保证线程独占变量,避免数据冲突;有序性涉及指令重排序,确保特定操作的执行顺序;可见性则关乎线程间的数据同步,确保更新的变量对所有线程可见。了解这些概念对于理解多线程编程至关重要。
摘要由CSDN通过智能技术生成

1. 三大性质简介

synchronized: 具有原子性,有序性和可见性   volatile:具有有序性和可见性
在并发编程中分析线程安全的问题时往往需要切入点,那就是 两大核心 :JMM抽象内存模型以及happens-before规则(在 这篇文章 中已经经过了),三条性质: 原子性,有序性和可见性 。关于 synchronized volatile 已经讨论过了,就想着将并发编程中这两大神器在  原子性,有序性和可见性 上做一个比较,当然这也是面试中的高频考点,值得注意。

2. 原子性

原子性是指 一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着“同生共死”的感觉 。及时在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程所干扰。我们先来看看哪些是原子操作,哪些不是原子操作,有一个直观的印象:
int a = 10; //1
a++; //2
int b=a; //3
a = a+1; //4
上面这四个语句中只 有第1个语句是原子操作 ,将10赋值给线程工作内存的变量a,而语句2(a++),实际上包含了三个操作:1. 读取变量a的值;2:对a进行加一的操作;3.将计算后的值再赋值给变量a,而这三个操作无法构成原子操作。对语句3,4的分析同理可得这两条语句不具备原子性。当然, java内存模型 中定义了8中操作都是原子的,不可再分的。
  1. lock(锁定):作用于主内存中的变量,它把一个变量标识为一个线程独占的状态;
  2. unlock(解锁):作用于主内存中的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
  3. read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便后面的load动作使用;
  4. load(载入):作用于工作内存中的变量,它把read操作从主内存中得到的变量值放入工作内存中的变量副本
  5. use(使用):作用于工作内存中的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作;
  6. assign(赋值):作用于工作内存中的变量,它把一个从执行引擎接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作;
  7. store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送给主内存中以便随后的write操作使用;
  8. write(操作):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。
上面的这些指令操作是相当底层的,可以作为扩展知识面掌握下。那么如何理解这些指令了?比如,把一个变量从主内存中复制到工作内存中就需要执行read,load操作,将工作内存同步到主内存中就需要执行store,write操作。注意的是: java内存模型只是要求上述两个操作是顺序执行的并不是连续执行的 。也就是说read和load之间可以插入其他指令,store和writer可以插入其他指令。比如对主内存中的a,b进行访问就可以出现这样的操作顺序: read a,read b, load b,load a
由原子性变量操作read,load,use,assign,store,write,可以 大致认为基本数据类型的访问读写具备原子性 (例外就是long和double的非原子性协定)
synchronized
上面一共有八条原子操作,其中六条可以满足基本数据类型的访问读写具备原子性,还剩下lock和unlock两条原子操作。如果我们需要更大范围的原子性操作就可以使用lock和unlock原子操作。尽管jvm没有把lock和unlock开放给我们使用,但jvm以更高层次的指令monitorenter和monitorexit指令开放给我们使用,反应到java代码中就是---synchronized关键字,也就是说 synchronized满足原子性
volatile 我们先来看这样一个例子:
public class VolatileExample {
private static volatile int counter = 0;
 
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值