资讯专栏INFORMATION COLUMN

理解Java中的Volatile关键字(demo)

codecraft / 2013人阅读

摘要:现在的处理器,一般是会有多个的,每个线程可能运行在不同的,那么线程修改完成的值,是首先保存在中去。考虑这样一种情况现在有两个线程,线程和线程,他们不时会去读取这个共享变量。

什么是volatile

关键字volatile 提供了Java 虚拟机中最轻量级的同步机制。在meidium 中有篇文章说:Volatile specifier is used to indicate that a variable’s value can be modified by multiple threads simultaneously

当你使用了volatile之后,那么这个变量会有如下的特性:

保证此变量对所有的线程的可见性

禁止指令重排序优化

对于第一条的内容,volatile是如何保证读写操作对所有的线程可见?

这里涉及到可见性的问题。

对于普通的变量来说,每个线程要想修改变量的值,首先从主存(JMM的定义,在JVM中,大致是可以对应到堆内存的)中拷贝值到自己所属的CPU cache中去。现在的处理器,一般是会有多个CPU的,每个线程可能运行在不同的CPU, 那么线程修改完成的值,是首先保存在CPU cache中去。此时其他的线程是察觉不到修改的结果的,这就造成了并发模型中的可见性问题。

考虑这样一种情况:

public class SharedObject { 
   public int counter = 0;
}

现在有两个线程, 线程1和线程2, 他们不时会去读取这个共享变量。如果counter没有声明volatile这个关键字,那么此时就无法保证counter的值何时从CPU缓存写回到主存。这意味着,counter在CPU cache中的值和主存中的会不一致。

但是如果声明了volatile的话,对volatile变量进行写操作的话,那么JVM就会向处理器发送一条LOCK前缀的指令,将这个变量所在缓存行中的数据写回到系统内存。

写回的过程,为了保证各个处理器的缓存是一一致的,就会实现缓存一致性协议。

缓存不停地窥探总线上发生的数据交换,来检查自己的数据是不是已经过期了。如果发现此时缓存行中的值已经失效的话,就会将当前缓存行中的值设置为无效状态。处理器要用到这个值的话,就会从内存中重新获取这个值。

禁止指令重排序

指令重排序是指CPU采用了允许将多条指令不按照程序规定的顺序分开发送给各相应的电路单元处理

TODO --

参考:

https://blog.usejournal.com/j...

https://medium.com/@siddhusin...

https://www.cnblogs.com/dolph...

《Java特种兵》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75209.html

相关文章

  • 《深入理解 Java 内存模型》读书笔记

    摘要:前提深入理解内存模型程晓明著,该书在以前看过一遍,现在学的东西越多,感觉那块越重要,于是又再细看一遍,于是便有了下面的读书笔记总结。同步同步是指程序用于控制不同线程之间操作发生相对顺序的机制。线程之间的通信由内存模型控制。 showImg(https://segmentfault.com/img/remote/1460000013474312?w=1920&h=1271); 前提 《深...

    xuexiangjys 评论0 收藏0
  • 《深入理解 Java 内存模型》读书笔记

    摘要:前提深入理解内存模型程晓明著,该书在以前看过一遍,现在学的东西越多,感觉那块越重要,于是又再细看一遍,于是便有了下面的读书笔记总结。同步同步是指程序用于控制不同线程之间操作发生相对顺序的机制。线程之间的通信由内存模型控制。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6RtPu3BNx3zps1JhSmPICRw7QgeOmxOfTb...

    姘存按 评论0 收藏0
  • 【J2SE】java并发基础

    摘要:的线程机制是抢占式。会让出当多个线程并发的对主存中的数据进行操作时,有且只有一个会成功,其余均失败。和对象只有在困难的多线程问题中才是必须的。 并发简述 并发通常是用于提高运行在单处理器上的程序的性能。在单 CPU 机器上使用多任务的程序在任意时刻只在执行一项工作。 并发编程使得一个程序可以被划分为多个分离的、独立的任务。一个线程就是在进程中的一个单一的顺序控制流。java的线程机制是...

    tianyu 评论0 收藏0
  • java 键字总结

    摘要:关键字总结有个关键字,它们是接下来对其中常用的几个关键字进行概括。而通过关键字,并不能解决非原子操作的线程安全性。为了在一个特定对象的一个域上关闭,可以在这个域前加上关键字。是语言的关键字,用来表示一个域不是该对象串行化的一部分。 java 关键字总结 Java有50个关键字,它们是: abstract do implements private ...

    honmaple 评论0 收藏0
  • 理解java Volatile 键字

    摘要:最近在看多线程相关,看到这篇来自大神关于关键字的讲解感觉非常详细易懂,特此转载一下。如果对增加声明则所有线程对的写都会立即刷新到主存中,而且所有对的读也都直接从主存中去读。 最近在看java多线程相关,看到这篇来自大神Jakob Jenkov关于Volatile关键字的讲解感觉非常详细易懂,特此转载一下。原文链接:http://tutorials.jenkov.com/j... 内存可...

    ConardLi 评论0 收藏0

发表评论

0条评论

codecraft

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<