Java:volatile的理解与应用
2016-03-09 17:08
411 查看
i = i+1
当程序执行这条语句时,会先从主存中读取i的值,然后复制一份到高速缓存中,然后cpu执行指令对i进行加1操作,然后将数据写入高速缓存,最后将高速缓存中的i最新的值刷新到主存当中。
并发中的3个概念:
1.原子性:一个操作或多个操作要么全部执行并且执行的过程不会被任何因素打断,要么全部不执行。Java中对基础数据类型的变量的读取和赋值操作是原子性操作。
2.可见性:多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。Java中通过volatile关键字来保证可见性。
3.有序性:程序执行的顺序按照代码的先后顺序。
场景:
(1)比如类中有成员int x, 下面两句连着的:
x=5;
x++;
如果单线程的话执行到第二句x的值一定是6,但是如果两个线程都可以访问此类的同一个对象,那在执行完第一句后第二句前,说不定x就给改成其他值了,x++的结果就不一定是6了。这种情况下应该将x声明为volatile,否则编译器也许会作出你意想不到的优化,使得编译后的程序非你所愿。比如说编译器看见这两句,你又不声明x为volatile,那编译器就觉得第二句后x一定是6,它就直接把这两句优化成x=6了。
当程序执行这条语句时,会先从主存中读取i的值,然后复制一份到高速缓存中,然后cpu执行指令对i进行加1操作,然后将数据写入高速缓存,最后将高速缓存中的i最新的值刷新到主存当中。
并发中的3个概念:
1.原子性:一个操作或多个操作要么全部执行并且执行的过程不会被任何因素打断,要么全部不执行。Java中对基础数据类型的变量的读取和赋值操作是原子性操作。
2.可见性:多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。Java中通过volatile关键字来保证可见性。
3.有序性:程序执行的顺序按照代码的先后顺序。
场景:
(1)比如类中有成员int x, 下面两句连着的:
x=5;
x++;
如果单线程的话执行到第二句x的值一定是6,但是如果两个线程都可以访问此类的同一个对象,那在执行完第一句后第二句前,说不定x就给改成其他值了,x++的结果就不一定是6了。这种情况下应该将x声明为volatile,否则编译器也许会作出你意想不到的优化,使得编译后的程序非你所愿。比如说编译器看见这两句,你又不声明x为volatile,那编译器就觉得第二句后x一定是6,它就直接把这两句优化成x=6了。
public static volatile int x = 0; public static void add() { x = 5; x++; if (x != 6) System.out.println(i); } public static void main(String[] args) throws InterruptedException { Runnable runnable = new Runnable() { @Override public void run() { for (int j = 0; j < Integer.MAX_VALUE / 10000; j++) { _Volatile2.add(); } } }; ExecutorService es = Executors.newFixedThreadPool(3); es.execute(runnable); es.execute(runnable); es.shutdown(); while (!es.awaitTermination(1, TimeUnit.MILLISECONDS)) { System.out.println("线程池没有关闭"); } } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树