Volatile关键字

来源:互联网 发布:反演变换知乎 编辑:程序博客网 时间:2024/06/08 02:47

Volatile关键字

参考:

http://blog.csdn.net/jsonChumpKlutz/article/details/78364332

http://blog.csdn.net/chenloxiaoea/article/details/47041227

http://blog.csdn.net/seu_calvin/article/details/52370068

 

线程的内存模型:


1、      线程从主内存取得的对象,仅仅是对象副本,线程内修改不影响主内存。

2、      当我们修改完共享变量的时候,需要把改过的变量写入主存中,这样才能让其他线程获取到正确的值。

3、      每个线程私有工作区间别的线程是无法访问的。

 

Jvm的原子性、可见性、有序性

原子性:

对基本类型变量的读取和赋值操作是原子性操作,即这些操作是不可中断的,要么执行完毕,要么就不执行。

Eg:

x =3;   //语句1

y =4   //语句2

z = x+y ;//语句3

x++;    //语句4

这里面的操作只有语句1和语句2是原子性的操作,语句3,4不是原子性的操作;因为再语句3中包括了三个操作,1是先读取x的值,2读取y的值,3将z的值写入内存中。语句4的解释是一样的。一般的一个语句含有多个操作该语句就不是原子性的操作,只有简单的读取和赋值才是原子性的操作。

可见性

就是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改结果,另一个线程马上就能看到。

有序性

Java内存模型允许编译器和处理器对指令进行重排序,虽然重排序不会影响到单线程的正确性,但是会影响到多线程的正确性。

 

 Volatile关键字

作用:

1.不保证原子性。

2.保证有序性。

3.保证可见性。

当用volatile修饰共享变量的时候,线程访问到该变量的时候都回去主存中去取该变量的值,它的工作内存中的缓存将失效,这样就保证了每个线程访问该变量的时候都是从主存中读写的。这就是为什么使用Volatile关键字来修饰线程间共享变量。

使用:


注意点:

volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正确性”,也就是说不保证线程执行的有序性。(也就是说,volatile变量对于每次使用,线程都能得到当前volatile变量的最新值。但是volatile变量并不保证并发的正确性),jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的。所以说volatile是线程不安全的。

synchronized

这里提到volatile就提一下synchronized。

Synchronized可作用于对象、方法。即可保证可见性,又能够保证原子性。

可见性体现在:通过synchronized或者Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存中。

原子性表现在:要么不执行,要么执行到底。

相对于volatile因为其要保证原子性,就影响执行效率。在不需要强调执行循序的时候我们就用volatile就好了。

 

 

 

 

 

 

 

原创粉丝点击