java并发机制的底层实现原理(一):volatile深入分析

     java代码最终会被类加载器加载到JVM中,然后转化为汇编指令在CPU上执行。java中所使用的并发机制依赖于JVM的实现和CPU的指令。

1.volatile的应用

volatile是一个轻量级的synchronize,它保证了共享变量的可见性,确保了所有线程看到这个变量的值是一致的——变量一经修改所有的线程都可知道,都可以获得共享变量的最新值。但是volatile并不能保证原子性。

1.1为何会存在可见性问题?

CPU为了提高处理速度,并不会直接和内存进行通信,而是存在着多级内部缓存。第一次访问内存中的某个数据,会先将内存中的数据读取到CPU缓存中,下次再访问时,就直接可以访问缓存而不是重新读取内存,修改时,也可以直接修改缓存中的数据。但是,缓存中的数据写回到内存中是不确定的,因此就有可能多个CPU中缓存的数据时不一致的,这就导致了可见性问题。

1.2volatile实现的底层原理——volatile是如何解决可见性问题的

当一个变量被volatile修饰时,如果存在写操作,也就是说要改变数据的时候,在底层汇编代码中,会多一条lock指令。这条lock指令干了两件事。

一:首先它会立即的将缓存中的数据写回到内存中。而且在写回时,会独占共享内存——即阻止两个CPU同时去修改共享变量。这保证了内存中的数据一定是最新的。

二:然后这个写回操作会导致其他CPU中的缓存无效。不同的CPU采用了不同的策略来实现这一点。有的通过嗅探技术,有的采用了控制协议。总之,这保证了一旦内存中的数据被更新后,下次访问CPU中的缓存一定能得到内存中的新值。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中的 volatile 关键字可以保证多线程之间对变量的可见性和有序性,但是它并不能保证原子性。下面是 volatile 底层实现原理: 1. 可见性:当一个变量被 volatile 修饰时,每次修改变量的值时,Java 内存模型都会强制将该变量的值刷新到主内存中,而每次读取该变量时,都会从主内存中读取最新的值。这样就可以保证多个线程之间对变量的修改是可见的。 2. 有序性:volatile 关键字还可以保证变量的读写操作是按照一定的顺序进行的。即当一个线程写入变量时,其它线程在读取该变量之前,必须先从主内存中读取该变量的最新值,而不是使用自己线程的缓存值。这样可以避免出现类似于指令重排的问题。 在底层实现上,volatile 关键字会在变量的读写操作前后插入内存屏障(Memory Barrier)指令,以保证变量的可见性和有序性。 内存屏障分为三种类型: 1. Load Barrier:插入在读操作前面,用于防止读操作重排到内存屏障之后。 2. Store Barrier:插入在写操作后面,用于防止写操作重排到内存屏障之前。 3. Full Barrier:插入在读操作前面和写操作后面,用于防止读操作和写操作重排到内存屏障之后和之前。 在 Java 中,volatile 关键字会在变量的读操作前插入 Load Barrier,而在变量的写操作后插入 Store Barrier。 需要注意的是,虽然 volatile 关键字可以保证多线程之间对变量的可见性和有序性,但是它并不能保证变量的原子性。如果需要保证变量的原子性,可以使用 synchronized 关键字或者 atomic 类来实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值