您的位置:首页 > 其它

Volatile关键字的可见性与原子性

2017-03-04 00:00 127 查看
链接:https://www.nowcoder.com/questionTerminal/521a37038afc4dd49f3d92a12b9a5907?toCommentId=403940
来源:牛客网
记录以下我在牛客回答的一个问题,即目前的肤浅理解。

1.volatile修饰的变量是读可见性的,什么意思呢,就是所有线程读取该变量的值都是正确的,变量写入这一动作,会被编译成机器指令,并且,是先写入到当前线程的工作内存而不是主内存(不懂的看看java 内存模型去),但是volatile修饰的变量的修改写入动作会被直接写入主内存,写入的同时会通过总线发出信号宣告其他线程的内存区该变量的值无效(即过时的),当其他线程去读该变量的值的时候,会发现工作内存的值过时了,就会到主内存去读该变量的值,所以是读可见性的。

2. 为什么不是线程安全的呢?这是因为原子性问题,什么是原子性?大家知道cpu工作是以时间片的方式分配cpu资源,当一个线程正在执行的时候,如果此时失去时间片,那么它所有的工作都要暂停,原子性就是:一个完整不再能分割的操作。即使是时间片结束,也要完成当前的原子操作,否则不允许切换。 Synchronized:保证可见性和原子性, 在Java内存模型中,synchronized规定,线程在加锁时 ,先清空工作内存→在主内存中拷贝最新变量的副本到工作内存→执行完代码→将更改后的共享变量的值刷新到主内存中→释放互斥锁 。参java并发编程艺术与博客http://blog.csdn.net/guyuealian/article/details/52525724
http://www.cnblogs.com/mengyan/archive/2012/08/22/2651575.html
---------------------------------2017年10月24日17:37:39补充volatile使用场景

Volatile 变量具有
synchronized
的可见性特性,但是不具备原子性。这就是说线程能够自动发现 volatile 变量的最新值。所以volatile修饰的变量其状态的改变不能依赖原来的值(如:i++这种就依赖原来的)。volatile可以用于修饰多个线程的共享标记变量,如boolean类型判断是否被线程消费过等。

参考http://blog.csdn.net/vking_wang/article/details/9982709
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: