volatile与synchronized的区别

一、锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)编程

  互斥即一次只容许一个线程持有某个特定的锁,所以可以使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程可以使用该共享数据。缓存

  可见性要更加复杂一些,它必须确保释放锁以前对共享数据作出的更改对于随后得到该锁的另外一个线程是可见的 —— 若是没有同步机制提供的这种可见性保证,线程看到的共享         变量多是修改前的值或不一致的值,这将引起许多严重问题。(竞态条件)安全

二、在Java中,为了保证多线程读写数据时保证数据的一致性,能够采用两种方式:多线程

  同步:如用synchronized关键字,或者使用锁对象spa

  使用volatile关键字:用一句话归纳volatile,它可以使变量在值发生改变时能尽快地让其余线程知道。线程

三、volatile详解对象

 当一个变量定义为volatile后,它将具有两种特性:1. 可见性,2. 禁止指令重排序。排序

    首先,咱们要意识到有这样的现象:编译器为了加快程序运行速度,对一些变量的写操做会如今寄存器或CPU缓存上进行,最后写入内存。而在这个过程当中,变量的新值对其它线程是不可见的。内存

    可见性:当对volatile标记的变量进行修改时,会将其它缓存中存储的修改前的变量清除,而后从新读取。这里从哪读还没有明确,通常来讲应该是先在进行修改的缓存A中修改成新值,而后通知其它缓存清除掉此变量,当其它缓存B中的线程读取此变量时,会向总线发送消息,这是存储新值的缓存A获取到消息,将新值传给B,最后将新值写入内存。编译器

 

volatile的做用是被其修饰的变量每次刷新时,都会刷新上述步骤。

四、volatile与synchronized

   1)volatile本质是告诉JVM当前变量在寄存器中的值是不肯定的,须要从主存中读取。synchronized则是锁定当前变量,只有当前线程能够访问该变量,其它线程被阻塞。

   2)volatile仅能使用在变量级别,synchronized则可使用在变量、方法

   3)volatile仅能实现变量修改的可见性,而synchronized则能够保证变量修改的可见性和原子性《Java编程思想》上说,定义long或double时,若是使用volatile关键字(简单的赋值与返回操做),就会得到原子性。(常规状态下,这两个变量因为其长度,其操做不是原子的)

   4)volatile不会形成线程阻塞,synchronized形成线程阻塞。

   5)使用volatile而不是synchronized的惟一安全状况是类中只有一个可变的域

五、当一个域的值依赖于它以前的值时,volatile就没法工做了,如n=n+1,n++等。若是某个域的值受到其余域的值的限制,那么volatile也没法工做,如Range类的lower和upper边界,必须遵循lower<=upper的限制。

六、使用volatile而不是synchronized的惟一安全的状况是类中只有一个可变的域。

相关文章
相关标签/搜索