您的位置:首页 > 编程语言 > Java开发

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了。

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 volatile 并发 i++