java 并发之 volatile

实例:

两个线程同时执行的情况下,执行i++ 操作,i初始化为1,得到的结果并非为3,而是2.过程为:

线程1和2 同时从主存中获取i 的值并写入缓存,在分别执行+1 操作,之后再分别写入主存,这时出现了最终主存的值为2的情况。这个是因为线程内操作对其他线程不可见,解决缓存一致性的方案有:

  1. 通过在总线加LOCK#锁的方式;

  2. 通过缓存一致性协议。

但是方案1的缺点是总线加锁会出现阻塞的情况,效率低。

方案2的核心思想是:缓存一致性协议(MESI协议)它确保每个缓存中使用的共享变量的副本是一致的。当某个CPU在写数据时,如果发现操作的变量是共享变量,则会通知其他CPU告知该变量的缓存行是无效的,因此其他CPU在读取该变量时,发现其无效会重新从主存中加载数据。

多线程并发的特点来源于:可见性,原子性和有序性

特点:

1、volatile 无法保证原子性操作(可理解为指令级别,java 对基本的数据类型的赋值操作进行了原子性操作的保证。但long和double 不是),

2、volatile 可保证可见性:当一个变量被volatile修饰后,表示着线程本地内存无效,当一个线程修改共享变量后他会立即被更新到主内存中,当其他线程读取共享变量时,它会直接从主内存中读取。当然,synchronize和锁都可以保证可见性。

3、在Java内存模型中,为了效率

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值