Java 高效并发之volatile关键字解析
2016-08-30 15:35
323 查看
摘录
1、计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。
Java内存模型规定所有的变量(这里的变量指共享变量,存在线程间的访问竞争,包括实例字段、静态字段、构成数组的元素,但不包括局部变量与方法参数因为它们是线程私有的不会被共享)都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。
Java内存模型中的操作指令(8个,都是原子操作):lock、unlock、read、load、use、assign、store、write
Java内存模型与硬件内存模型的类比关系如下:
class Test extends Thread { static volatile int num = 0; public static void increament() { num++; } public static void main(String[] args) { // TODO Auto-generated method stub int loopCount = 10, increamentPerLoop = 1000; long timeStart = System.currentTimeMillis(); for (int i = 0; i < loopCount; i++) { new Thread(new Runnable() { public void run() { for (int i = 0; i < increamentPerLoop; i++) { increament(); } } }).start(); } while (Thread.activeCount() > 1) { Thread.yield(); } System.out.printf("num:%d, time used:%dms\n", num, (System.currentTimeMillis() - timeStart));// num结果不是loopCount*increamentPerLoop,说明volatile没有确保原子性。其原因是虽然确保每次访问num得到的是最新的值,但num++不是原子操作,导致多线程并行时num的更新可能被覆盖 } }
View Code
volatile的原理和实现机制:
“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
总结:
原子性:synchronized
可见性:volatile、synchronized、final
有序性:volatile、synchronized
参考资料
http://www.cnblogs.com/dolphin0520/p/3920373.html《深入理解Java虚拟机》
相关文章推荐
- 导入安全证书到jdk步骤详细说明-原
- java读取properties配置文件的配置项
- 泛型 T 获取
- java 中对lis进行排序时,排序失效解决
- java 继承
- Java并发编程:深入剖析ThreadLocal
- java5 线程并发库
- 将获取到的Json存入java对象
- java的反射
- java线程中yield(),sleep(),wait()区别详解
- java 文章抓取
- Java线程基础
- 关于bean不能被创建的问题
- idea maven springmvcweb项目
- 如何使用intelij IDEA 显示一个类的所有方法?与eclipse的outline视图类似
- 写给Java开发者
- hibernate 出现Caused by: java.sql.SQLException: Column 'id' not found.异常
- java代码优化总结
- java设计模式之中介者模式
- Java并发编程:线程池的使用