Java Volatile关键字和 Synchronized关键字的区别

在网上看了一些博客,在这里自己总结一下,以便以后自己可以看得懂。。

Volatile关键字的作用是不让线程在CPU缓存或者寄存器中进行写操作 因为线程在修改一个变量的时候  为了提高效率 通常会在寄存器或者CPU缓存中先进行修改,这一过程对其他线程是不可见得,然后再写入内存,在这一过程中 如果有其他线程又对这一数据进行了修改,那么就会产生数据的不同步。因此为了避免这一现象,可以使用Volatile关键字来对变量进行修饰,使其不在寄存器和CPU缓存中进行 直接操作内存,这样就可以让所有线程及时得到数据修改的消息,保证数据的一致性。但是使用volatile关键字会有性能上的消耗,因为直接操作主存比操作缓存麻烦


Synchronized关键字是对代码块加锁的操作   他操作的过程如下  

1.   线程从监听器获取对象的锁。(这里假设监听器非锁,否则线程只有等到监听器解锁才能获取对象锁)
2.   线程内存更新所有的变量,也就是说他将读取主内存中的变量使自己的变量保证有效。(JVM会使用一个“脏”标志来最优化过程,使得仅仅具有“脏”标志变量被更新。详细的情况查询JAVA规范的17.9)
3.   代码块被执行
4.   任何变量的变更将被写回到主内存中。
5.   线程释放对象的锁给监听器。

综上所述,volatile 是来保证主存中的数据始终对所有线程可见,也就是线程获取到的都是主存中正确的值   而synchronized 是给某一部分代码加锁,使得他在操作某一些变量的时候其他线程都不可以操作,这样就保证了数据不会被同时修改或者读取,可以实现多个数据的同步,因此synchronized更耗资源 并且更好用一些 。


最后复制一下网上最常见的二者区别。。。:

1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
3.volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化
 
红字体部分的原因如下:
线程A修改了变量还没结束时,另外的线程B可以看到已修改的值,而且可以修改这个变量,而不用等待A释放锁,因为Volatile 变量没上锁


你可能感兴趣的:(Java Volatile关键字和 Synchronized关键字的区别)