码迷,mamicode.com
首页 > 其他好文 > 详细

volatile关键字(2)

时间:2021-06-30 18:19:33      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:其他   变量   模型   缓存   编译器优化   str   共享变量   一个   可见   

可见性与原子性

  ⑴可见性:一个线程对变量的修改,能够即使被其他线程"看到"

  ⑵原子性:不可再分的操作,即不能拆分成多步的操作。比如"a = 1;"和 "return a;"这样的操作都具有原子性。类似"a += b"这样的操作不具有原子性,

          在   某些JVM中"a += b"可能要经过这样三个步骤:
    ① 取出a和b
    ② 计算a+b
    ③ 将计算结果写入内存

 

Synchronized:保证可见性和原子性

在Java内存模型中,Synchronized规定,线程在加锁时,先清空工作内存  -? 从主存中拷贝最新变量的副本到工作内存  -? 执行完代码  -? 将更改后的共享变量的值刷回到主存中  -?  释放互斥锁

 

Volatile:保证可见性,不保证操作原子性

Volatile实现内存可见性是通过store和load指令完成的;也就是对volatile变量执行写操作时,会在写操作后加入一条store指令,即强迫线程将最新的值刷新到主内存中;而在读操作时,会加入一条load指令,即强迫从主内存中读入变量的值。但volatile不保证volatile变量的原子性,例如:

  

1.volatile关键字不能保证操作原子性

2.保证内存可见性,即多个线程获取的数据是同一份

3.保证有序性,即被volatile声明的变量不会被编译器优化

4.保证happens-before

5.volatile只能作用于变量

 

volatile本质是在告诉JVM当前变量在寄存器中的值是不确定的,使用前,需要先从主存中读取,因此可以实现可见性。而对n=n+1,n++等操作时,volatile关键字将失效,不能起到像synchronized一样的线程同步(原子性)的效果。

1.保证重排序不会把后面的指令放到volatile声明变量前面,也不会把前面的放到后面

2.强制对缓存的修改操作立刻写入到主存

3.如果是写操作,会导致其他cpu中的缓存失效

 

volatile关键字(2)

标签:其他   变量   模型   缓存   编译器优化   str   共享变量   一个   可见   

原文地址:https://www.cnblogs.com/MadYanYan/p/11745788.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!