美文网首页面试
java中的volatile和synchronized

java中的volatile和synchronized

作者: Ten_Minutes | 来源:发表于2016-07-14 08:57 被阅读115次

这个可能是最好的对比volatile和synchronized作用的文章了。volatile是一个变量修饰符,而synchronized是一个方法或块的修饰符。所以我们使用这两种关键字来指定三种简单的存取变量的方式。

int i1;                       int geti1() {return i1;}

volatile int i2;int geti2() {return i2;}

int i3;          synchronized int geti3() {return i3;}

geti1()在当前线程中立即获取在i1变量中的值。线程可以获得变量的本地拷贝,而所获得的变量的值并不一定与其他线程所获得的值相同。特别是,如果其他的线程修改了i1的值,那么当前线程获得的i1的值可能与修改后的值有所差别。实际上,Java有一种主内存的机制,使用一个主内存来保存变量当前的正确的值。线程将变量的值拷贝到自己独立的内存中,而这些线程的内存拷贝可能与主内存中的值不同。所以实际当中可能发生这样的情况,在主内存中i1的值为1,线程1和线程2都更改了i1,但是却没把更新的值传回给主内存或其他线程中,那么可能在线程1中i1的值为2,线程2中i1的值却为3。

另一方面,geti2()可以有效的从主内存中获取i2的值。一个volatile类型的变量不允许线程从主内存中将变量的值拷贝到自己的存储空间。因此,一个声明为volatile类型的变量将在所有的线程中同步的获得数据,不论你在任何线程中更改了变量,其他的线程将立即得到同样的结果。由于线程存取或更改自己的数据拷贝有更高的效率,所以volatile类型变量在性能上有所消耗。

那么如果volatile变量已经可以使数据在线程间同步,那么synchronizes用来干什么呢?两者有两方面的不同。首先,synchronized获取和释放由监听器控制的锁,如果两个线程都使用一个监听器(即相同对象锁),那么监听器可以强制在一个时刻只有一个线程能处理代码块,这是最一般的同步。另外,synchronized还能使内存同步。在实际当中,synchronized使得所有的线程内存与主内存相同步。所以geti3()的执行过程如下:

1.线程从监听器获取对象的锁。(这里假设监听器非锁,否则线程只有等到监听器解锁才能获取对象锁)

2.线程内存更新所有的变量,也就是说他将读取主内存中的变量使自己的变量保证有效。(JVM会使用一个“脏”标志来最优化过程,使得仅仅具有“脏”标志变量被更新。详细的情况查询JAVA规范的17.9)

3.代码块被执行(在这个例子中,设置返回值为刚刚从主内存重置的i3当前的值。)

4.任何变量的变更将被写回到主内存中。但是这个例子中geti3()没有什么变化。

5.线程释放对象的锁给监听器。

所以volatile只能在线程内存和主内存之间同步一个变量的值,而synchronized则同步在线程内存和主内存之间的所有变量的值,并且通过锁住和释放监听器来实现。显然,synchronized在性能上将比volatile更加有所消耗。

=============关于两者的区别===================

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

2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的

3.volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性

4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。

5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化

红字体部分的原因如下:

线程A修改了变量还没结束时,另外的线程B可以看到已修改的值,而且可以修改这个变量,而不用等待A释放锁,因为Volatile 变量没上锁

相关文章

  • java 高并发中volatile的实现原理

    java 高并发中volatile的实现原理 摘要: 在多线程并发编程中synchronized和Volatile...

  • volatile关键字

    java中关键字volatile的作用; volatile vs synchronized的区别 Java并发编...

  • Java中的volatile

    Java中的volatile 在多线程并发编程中Synchronized 和 Volatile都扮演者重要的角色,...

  • java并发之volatile

    在Java并发编程中,volatile和synchronized都扮演者重要的角色。volatile又被成为轻量级...

  • Java面试之volatile和synchronized及Loc

    面试中经常会遇到以下的问题:Java中的volatile和synchronized的区别?Java中的Lock和s...

  • 【同步】

    java中的volatile和synchronized 一个volatile类型的变量不允许线程从主内存中将变量的...

  • 总结

    java基础 Java中多态的理解 反射 Java序列化与反序列化 Volatile和Synchronized e...

  • Java中Volatile和synchronized

    JMM 内存模型:Java Memory Model问题:并发过程中如何处理可见性 原子性和有序性问题 并发编程中...

  • Java基础-浅析解决并发的几种方式

    前言 在上一篇中,我们讨论了Java中的关键字volatile和synchronized Java基础-浅谈关键字...

  • 6

    Java内存模型定义了Java语言中的synchronized、volatile和final等关键词对主存中变量读...

网友评论

    本文标题:java中的volatile和synchronized

    本文链接:https://www.haomeiwen.com/subject/qrsejttx.html