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

Java学习笔记(一)volatile与多线程

2014-05-09 12:57 344 查看
被问到Volatile,讲不清楚,回来好好补课。

几个相关的知识要理解:多线程,内存模型,乱序优化,锁,原子性,可见性

如果不定义为volatile,会发生什么

主内存中的数据,例如var,会被缓存在寄存器中,进行read/write操作之后,在某个时间复制回内存。在多核CPU上运行多线程的程序,共享变量会因为多个线程,产生多个寄存器中的缓存,在一个线程中的修改,被写回内存之前,其他线程是看不到的。



volatile的效果


一个共享变量var定义为volatile,那么,如果两个线程,a线程write,b线程在之后read,那么前者的操作结果一定会被后者读到,也即:b线程读到的一定是a线程write之后的结果(假设中间没有其他操作)

ref: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
根据Java语言规范,volatile保证了共享变量在多线程下的“可见性”

volatile如何保证可见性

编译器遇到volatile时,就会要求CPU不在寄存器中进行缓存,而是直接操作内存。

要更好地理解可见性,可以阅读Java语言规范的内存模型一节:http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4

原子性

在Java Tutorial中,对原子操作是这样描述的:

Reads and writes are atomic for reference variables and for most primitive variables (all types except
long
and
double
).
Reads and writes are atomic for all variables declared
volatile
(including
long
and
double
variables)

问题:一个对象,有两个int字段,i、j,要对它们分别加一。将这个对象定义为volatile能保证两个加一操作的一致性吗?答案显然是不能。

所以,第二句话中的all variables,我只能理解为primitive variables

实现复杂操作的原子性

还是离不开锁

两种锁,悲观锁,乐观锁

Synchronize属于悲观锁,用得很多了,不需赘述

乐观锁,在这里一般就指 CAS - Compare and Swap,不加锁,每次write操作之前,检查操作目标的当前状态是否和本线程中缓存的状态一致,如果不一致,则重新读取,重新尝试write操作。

阅读java.util.concurrent.atomic包中的源代码,可以看到大量调用了 sun.misc.Unsafe.compareAndSwapXxx()

Compare和Swap是两个动作,如何保障这两个动作的原子性,也即这两次操作期间没有其他线程修改操作目标?这就需要阅读sun.misc.Unsafe的源码,进行更深入的研究了。根据网上看到的资料,这部分是JNI方法。还没有去找这部分代码来读,以后有机会再继续学习。

下面这个网页是对 sun.misc.Unsafe 的一个介绍:http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

需要说的是,用Volatile和CAS,性能未必比synchronize/Lock好。需要具体情况具体分析。

网上关于应用Volatile的推荐原则如下:

(1)写入变量不依赖此变量的值,或者只有一个线程修改此变量

(2)变量的状态不需要与其它变量共同参与不变约束

(3)访问变量不需要加锁

小结

1. Java volatile 提供操作对象在多线程之间的可见性,volatile变量不会在寄存器中缓存,只保存在内存中

2. volatile本身不提供原子性,但可以结合 CAS 的方式,实现非阻塞的并行计算

3. 因为Java规范保证对原始数据类型操作的原子性,因此,对此类数据的访问,可以利用volatile实现不加锁的同步访问,但其性能未必是最优的

扩展阅读:

JSR 166 Concurrency Utilities

defungo的博客:深入浅出 Java Concurrency (2): 原子操作

Hsuxu的专栏 - JAVA CA原理深度分析

剖析为什么在多核多线程程序中要慎用volatile关键字
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: