前言
在并发编程中分析线程安全的问题时三条性质:原子性,有序性和可见性往往是非常重要的,本篇博客主要来用synchronized和volatile关键来进行对比。首先来看看宏观导图
核心
原子性
原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败。首先来synchronized
尽管jvm没有把lock和unlock开放给我们使用,但jvm以更高层次的指令monitorenter和monitorexit指令开放给我们使用,synchronized关键字满足原子性。
volatile是不满足原子性的.
如果让volatile保证原子性,必须符合以下两条规则:
- 运算结果并不依赖于变量的当前值,或者能够确保只有一个线程修改变量的值;
- 变量不需要与其他的状态变量共同参与不变约束
有序性
synchronized语义表示锁在同一时刻只能由一个线程进行获取,当锁被占用后,其他线程只能等待。因此,synchronized语义就要求线程在访问读写共享变量时只能“串行”执行,因此synchronized具有有序性。
volatile
在java内存模型中说过,为了性能优化,编译器和处理器会进行指令重排序;也就是说java程序天然的有序性可以总结为:如果在本线程内观察,所有的操作都是有序的;如果在一个线程观察另一个线程,所有的操作都是无序的。而用volatile修饰的话就操作重排序,从而避免这种情况。volatile包含禁止指令重排序的语义,其具有有序性。
可见性
可见性是指当一个线程修改了共享变量后,其他线程能够立即得知这个修改。synchronized,当线程获取锁时会从主内存中获取共享变量的最新值,释放锁的时候会将共享变量同步到主内存中。从而,synchronized具有可见性。同volatile,会通过在指令中添加lock指令,以实现内存可见性。因此, volatile具有可见性
总结
通过前面的总结,再次将synchronized和volatile总结:
synchronized: 具有原子性,有序性和可见性; volatile:具有有序性和可见性
标签:总结,变量,synchronized,可见,volatile,有序性,线程,多线程,三大 From: https://blog.51cto.com/u_15586641/5762063