volatile和sychronized

一、volatile详解

首先,我们应该有java内存模型的概念,编译器为了加快程序的运行速度,一般对变量的操作是先在cpu缓存或者寄存器上进行的,最后再写入内存,这个过程中对其他变量是不可见的。volatile修饰的变量就是解决内存可见性的问题,会使得所有的变量读写操作都直接刷到主存中。

左边cpu的线程从主存中读取obj.count = 1,在缓存中进行了更改,obj.count = 2,这个过程对于右边的cpu的线程是不可见的,因为这个变量还没有flush到主存中。如果将obj.count这个变量用volatile修饰,那么对变量obj.count 的修改会直接刷到主存中,那么对于右边的线程也是可见的,该线程拷贝的共享对象obj的中的变量count也变成了2。

volatile还有一个作用就是禁止指令重排序。

二、volatile的使用条件

1.对变量的写入操作不依赖当前值

2.该变量没有包含在具有其他变量的不变式中

三、volatile和sychronized的区别:

1.volatile的本质是告诉当前变量在寄存器中的值是不确定的,需要从主存中读取。sychronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。

2.volatile的使用仅能在变量级别,sychronized则可以作用在变量和方法上

3.volatile仅能实现变量修改的可见行,sychronized可以实现变量修改的可见行和原子性。

4.volatile不会造成线程阻塞,sychronized会造成线程阻塞。

5.当一个域的值依赖于它之前的值时,volatile就无法工作了,如 i = i + 1 ,i++;

   如果一个域上的值受到其他域的限制时,volatile也无法工作了,如Range类的lower和upper边界,必须遵循lower<=upper;

猜你喜欢

转载自www.cnblogs.com/liucg1/p/9047364.html