synchronized&volatile

在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,觉得使用这个关键字,在进行多线程并发处理的时候就能够万事大吉。java

Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。编程

 


synchronized 安全

同步块你们都比较熟悉,经过 synchronized 关键字来实现,全部加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程可以用多线程

synchronized 修饰的方法 或者 代码块。并发

 


volatilejvm

用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操做。优化

要使 volatile 变量提供理想的线程安全,必须同时知足下面两个条件:spa

  • 对变量的写操做不依赖于当前值。
  • 该变量没有包含在具备其余变量的不变式中。

实际上,这些条件代表,能够被写入 volatile 变量的这些有效值独立于任何程序的状态,包括变量的当前状态。 线程

第一个条件的限制使 volatile 变量不能用做线程安全计数器。虽然增量操做(x++)看上去相似一个单独操做,实际上它是一个由读取-修改-写入操做序列组成的组合操做,必须以原子方式执行,而 volatile 不能提供必须的原子特性。实现正确的操做须要使 x 的值在操做期间保持不变,而 volatile 变量没法实现这点。(然而,若是将值调整为只从单个线程写入,那么能够忽略第一个条件。) code

大多数编程情形都会与这两个条件的其中之一冲突,使得 volatile 变量不能像 synchronized 那样广泛适用于实现线程安全。清单 1 显示了一个非线程安全的数值范围类。它包含了一个不变式 —— 下界老是小于或等于上界。

 


一旦一个共享变量(类的成员变量、类的静态成员变量)被 volatile 修饰以后,那么就具有了两层语义:
  

在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,觉得使用这个关键字,在进行多线程并发处理的时候就能够万事大吉。

 

Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。

 

 

 


synchronized

同步块你们都比较熟悉,经过 synchronized 关键字来实现,全部加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程可以用

 

synchronized 修饰的方法 或者 代码块。

 

 

 


volatile

用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操做。

 

要使 volatile 变量提供理想的线程安全,必须同时知足下面两个条件:

 

  • 对变量的写操做不依赖于当前值。
  • 该变量没有包含在具备其余变量的不变式中。

 

实际上,这些条件代表,能够被写入 volatile 变量的这些有效值独立于任何程序的状态,包括变量的当前状态。

 

第一个条件的限制使 volatile 变量不能用做线程安全计数器。虽然增量操做(x++)看上去相似一个单独操做,实际上它是一个由读取-修改-写入操做序列组成的组合操做,必须以原子方式执行,而 volatile 不能提供必须的原子特性。实现正确的操做须要使 x 的值在操做期间保持不变,而 volatile 变量没法实现这点。(然而,若是将值调整为只从单个线程写入,那么能够忽略第一个条件。)

 

大多数编程情形都会与这两个条件的其中之一冲突,使得 volatile 变量不能像 synchronized 那样广泛适用于实现线程安全。清单 1 显示了一个非线程安全的数值范围类。它包含了一个不变式 —— 下界老是小于或等于上界。

 

 

 


一旦一个共享变量(类的成员变量、类的静态成员变量)被 volatile 修饰以后,那么就具有了两层语义:


  1)保证了不一样线程对这个变量进行操做时的可见性,即一个线程修改了某个变量的值,这新值对其余线程来讲是
    当即可见的。
  2)禁止进行指令重排序。
    volatile 本质是在告诉 jvm 当前变量在寄存器(工做内存)中的值是不肯定的,须要从主存中读取;
    synchronized 则是锁定当前变量,只有当前线程能够访问该变量,其余线程被阻塞住。
  1.volatile 仅能使用在变量级别;
    synchronized 则可使用在变量、方法、和类级别的
  2.volatile 仅能实现变量的修改可见性,并不能保证原子性;
    synchronized 则能够保证变量的修改可见性和原子性
  3.volatile 不会形成线程的阻塞;
    synchronized 可能会形成线程的阻塞。
  4.volatile 标记的变量不会被编译器优化;

    synchronized 标记的变量能够被编译器优化
 

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息