364高并发的三大特性—原子性有序性可见性

Posted huoyingfans

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了364高并发的三大特性—原子性有序性可见性相关的知识,希望对你有一定的参考价值。

最近正在系统的学习《java虚拟机》,有很多问题都值得仔细推敲,当我们知道了java内存的相关操作和规则,我们再整体回顾一下模型的特征。java内存模型是围绕着并发过程中如何处理原子性、可见性、有序性这3个特征来建立的,我们逐个来看一下哪些操作实现了这3个特征。如有错误,感谢同好指正。

一、原子性(Atomicity)

定义:即一个操作或者多个操作,要么全部执行并且不被打断,要么就都不执行。

关键字:synchronized

比如:从账户A向账户B转1000元,那么必然包括2个操作:从账户A减去1000元,往账户B加上1000元。这2个操作必须要具备原子性才能保证不出现一些意外的问题。
再比如:i = i+1;其中就包括,读取i的值,计算i,写入i。这行代码在java中是不具备原子性的,如果 多线程运行肯定会出问题。·

综上可知,对变量的写操作不依赖于当前值才是原子级别的,在多线程环境中才可以不用考虑多并发问题。比如:n=n+1、n++ 就不行。n=m+1才是原子级别的,实在没把握就使用synchronized关键字来代替volatile关键字。

二、可见性(Visibility)

定义:当一个线程修改了共享变量的值,其他线程会马上知道这个修改。当其他线程要读取这个变量的时候,最终会去内存中读取,而不是从缓存中读取。

关键字:volatile、synchronized、final

三、有序性(Ordering)

定义:虚拟机在进行代码编译时,对于那些改变顺序之后不会对最终结果造成影响的代码,虚拟机不一定会按照我们写的代码的顺序来执行,有可能将他们重排序。实际上,对于有些代码进行重排序之后,虽然对变量的值没有造成影响,但有可能会出现线程安全问题。

关键字:volatile、synchronized

volatile本身就包含了禁止指令重排序的语义,而synchronized关键字是由“一个变量在同一时刻只允许一条线程对其进行lock操作”这条规则明确的。

小结:

  1. synchronized关键字同时满足以上三种特性,但是volatile关键字不满足原子性。
  2. 在某些情况下,volatile的同步机制的性能确实要优于锁(使用synchronized关键字或java.util.concurrent包里面的锁),因为volatile的总开销要比锁低。
  3. 我们判断使用volatile还是加锁的唯一依据就是volatile的语义能否满足使用的场景(原子性)

 

以上是关于364高并发的三大特性—原子性有序性可见性的主要内容,如果未能解决你的问题,请参考以下文章

多线程&高并发深入理解JMM产生的三大问题原子性可见性有序性

并发特性

Java三大性质总结:原子性可见性以及有序性

voliate怎么保证可见性

java并发特性:原子性可见性有序性

并发基础并发的三大特性