java面试题之volatile的工作原理
volatile的特性:
- volatile可见性:对一个volatile的读,总可以看到对这个变量最终的写;
- volatile原子性:volatile对单个读/写具有原子性(32位Long、Double),但是复合操作除外,例如:i++;
- jvm底层采用“内存屏障”来实现volatile语义。
volatile的内存语义及实现:
在JMM中,线程之间的通信采用共享内存来实现的。
volatile内存语义是:
- 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新到主内存中;
- 当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,直接从主内存中读取共享变量。
volatile的底层实现是通过插入内存屏障,但是对于编译器来说,发现一个最优布置来最小化插入内存屏障的总数几乎是不可能的,所以,JMM采用保守策略。如下:
- 在每一个volatile写操作前面插入一个StoreStore屏障
- 在每一个volatile写操作后面插入一个StoreLoad屏障
- 在每一个volatile读操作后面插入一个LoadLoad屏障
- 在每一个volatile读操作后面插入一个LoadStore屏障
StoreStore屏障可以保证在volatile写之前,其前面的所有普通写操作都已经刷新到主内存中;
StoreLoad屏障的作用是避免volatile写与后面可能有的volatile读/写操作重排序
LoadLoad屏障用来禁止处理器把上面的volatile读与下面的普通读重排序
LoadStore屏障用来禁止处理器把上面的volatile读与下面的普通写重排序
java中volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次使用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。
在java中,可以使用synchronized和volatile来保证多线程之间操作的有序性。实现方式有所区别:
- volatile关键字会禁止指令重排;
- 2、synchronized关键字保证同一时刻只允许一条线程操作。 synchronized是万能,他可以同时满足三种特性,这其实也是很多人滥用synchronized的原因。
java面试题之volatile的工作原理的更多相关文章
- volatile的工作原理
volatile的特性: volatile可见性:对一个volatile的读,总可以看到对这个变量最终的写: volatile原子性:volatile对单个读/写具有原子性(32位Long.Doubl ...
- Java中的Annotation(2)----Annotation工作原理
Java中的Annotation(2)----Annotation工作原理 分类: 编程语言2013-03-18 01:06 3280人阅读 评论(6) 收藏 举报 上一篇文章已经介绍了如何使用JDK ...
- java面试题(一年工作经验)的心得
看面试题 正常人第一步肯定都会看面试题,我也不例外,在看的过程中,我发现有些文章写的不错,对我帮助不小值得推荐,如下: Java面试题全集(上) 很多基础的东西,建议先看. 各大公司Java后端开发面 ...
- 【死磕Java并发】-----深入分析volatile的实现原理
通过前面一章我们了解了synchronized是一个重量级的锁,虽然JVM对它做了很多优化,而下面介绍的volatile则是轻量级的synchronized.如果一个变量使用volatile,则它 ...
- Java web每天学之Servlet工作原理详情解析
上篇文章中我们介绍了Servlet的实现方式以及Servlet的生命周期,我们这篇文章就来介绍一下常用对象. 点击回顾:<Java Web每天学之Servlet的工作原理解析>:<J ...
- 认识volatile的工作原理
前言 在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”.可见性的意思是当 ...
- 【死磕Java并发】—–深入分析volatile的实现原理
通过前面一章我们了解了synchronized是一个重量级的锁,虽然JVM对它做了很多优化,而下面介绍的volatile则是轻量级的synchronized.如果一个变量使用volatile,则它比使 ...
- Java 线程池的介绍以及工作原理
在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.将需处理的任务的数量大 使用线程池的好处: 1. 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的消耗.2. 提高响应速度: ...
- Java并发包中CountDownLatch的工作原理、使用示例
1. CountDownLatch的介绍 CountDownLatch是一个同步工具,它主要用线程执行之间的协作.CountDownLatch 的作用和 Thread.join() 方法类似,让一些线 ...
随机推荐
- docker单主机网络
当你安装Docker时,它会自动创建三个网络.你可以使用以下docker network ls命令列出这些网络: [root@localhost ~]# docker network ls NETWO ...
- NOIP模拟赛 czy的后宫6
czy的后宫6 题目描述 众所周知的是丧尸czy有很多妹子(虽然很多但是质量不容乐观QAQ),今天czy把n个妹子排成一行来检阅.但是czy的妹子的质量实在……所以czy看不下去了.检阅了第i个妹子会 ...
- angular5 HttpInterceptor使用
HttpInterceptor接口是ng的http请求拦截器,当需要拦截http请求,可以实现该接口. 1.创建HttpInterceptor 的实现类,并使用@Injectable()注解 @Inj ...
- 【laravel】Laravel 5 TokenMismatchException on PHP 5.6.9
When I realized this was only happening in IE and Chrome, but not Firefox, it led me to the fix. The ...
- OpenCV中的绘图函数
OpenCV可以用来绘制不同的集合图形,包括直线,矩形,圆,椭圆,多边形以及在图片上添加文字.用到的绘图函数包括 cv2.line(),cv2.circle(),cv2.rectangle() ,cv ...
- PTA 7-2 符号配对
直接用栈模拟即可,数组可做,但因为这节数据结构是栈,为了期末考试还是手写一下栈的操作,值得注意的是,这道题用gets函数在PTA上会编译错误,用scanf("%[^\n]", st ...
- 查看 EGLIBC 版本
$ ldd --versionldd (Debian EGLIBC 2.13-38+deb7u1) 2.13
- BZOJ 4425: [Nwerc2015]Assigning Workstations分配工作站
难度在于读题 #include<cstdio> #include<algorithm> #include<queue> using namespace std; p ...
- luogu1578 奶牛浴场 枚举点最大子矩阵
建议看看王知昆dalao的论文,讲得很好 #include <algorithm> #include <iostream> #include <cstring> # ...
- luogu3371 【模板】单源最短路径 dijkstra堆优化
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> ...