Java关键字volatile和synchronized作用和区别

 更新时间:2020年06月19日 11:41:24   作者:无尽循环  
这篇文章主要为大家详细介绍了Java关键字volatile和synchronized的作用和区别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

volatile是变量修饰符,而synchronized则是作用于一段代码或方法;如下三句get代码:

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

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

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


geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。

geti2() 得到的是main memory的i2数值。一个变量声明为volatile,就意味着这个变量是随时会被其他线程修改的,因此不能将它cache在线程memory中。换句话说,一个变量经过volatile修饰后在所有线程中必须是同步的,任何线程中改变了它的值,所有其他线程立即获得了相同的值。所以,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的变量拷贝更为高效。

geti3()方法被synchronized修饰,用synchronized来修饰一个方法或者一个贷款的时候,能够保证在同一时刻最多只有一个线程执行该段代码。既然volatile关键字已经实现了线程间数据同步,又要synchronized干嘛呢?当两个并发线程访问同一个对象object中的这个synchronized(this)同步贷款时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块才能执行该代码块。然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时候,其他线程对object中所有其他synchronized(this)同步代码块的访问将被阻塞。当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁,结果,其他线程对该对象所有同步代码部分的访问都被暂时阻塞。

总结一下区别:

一,volatile是变量修饰符,而synchronized则作用于一段代码或者方法。

二,volatile只是在线程内存和main memory(主内存)间同步某个变量的值;而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 解决mybatis三表连接查询数据重复的问题

    解决mybatis三表连接查询数据重复的问题

    这篇文章主要介绍了解决mybatis三表连接查询数据重复的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Spring执行sql脚本文件的方法

    Spring执行sql脚本文件的方法

    这篇文章主要介绍了Spring执行sql脚本文件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • IntelliJ IDEA 2017.1.4 x64配置步骤(介绍)

    IntelliJ IDEA 2017.1.4 x64配置步骤(介绍)

    下面小编就为大家带来一篇IntelliJ IDEA 2017.1.4 x64配置步骤(介绍)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • java设计优化之单例模式

    java设计优化之单例模式

    这篇文章主要为大家详细介绍了java设计优化中的单例模式,深入学习java单例模式,感兴趣的朋友可以参考一下
    2016-03-03
  • SpringBoot整合liquibase及liquibase生成初始化脚本的方式

    SpringBoot整合liquibase及liquibase生成初始化脚本的方式

    这篇文章主要介绍了SpringBoot整合liquibase的相关资料,文中给大家介绍了liquibase生成初始化脚本的两种方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • java中String字符串删除空格的七种方式

    java中String字符串删除空格的七种方式

    在Java中从字符串中删除空格有很多不同的方法,本文主要介绍了java中String字符串删除空格的七种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • spring容器启动实现初始化某个方法(init)

    spring容器启动实现初始化某个方法(init)

    这篇文章主要介绍了spring容器启动实现初始化某个方法(init),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java获取本机IP地址的三种方法总结

    Java获取本机IP地址的三种方法总结

    这篇文章主要为大家详细介绍了java获取本机IP地址的三种方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Springboot+MDC+traceId日志中打印唯一traceId

    Springboot+MDC+traceId日志中打印唯一traceId

    本文主要介绍了Springboot+MDC+traceId日志中打印唯一traceId,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • Java中tomcat memecached session 共享同步问题的解决办法

    Java中tomcat memecached session 共享同步问题的解决办法

    这篇文章主要介绍了Java中tomcat memecached session 共享同步问题的解决办法的相关资料,需要的朋友可以参考下
    2015-10-10

最新评论