Difference Between Volatile and Synchronized Keywords in Java

 

volatile是一个变量修饰符synchronized修饰一段代码块和方法。

我们来看下下面的代码

int  i1 ;              

int  geti1(){ return  i1 ;}

volatile  int  i2 ;              

int  geti2(){ return  i2 ;}        

int  i3 ;

synchronized  int  geti3(){ return  i3 ;}

 

在这里,我们定义了三个整型变量:i1 ,i2,和i3 。而且,我们定义了三种相应的getter方法:geti1()geti2(),和geti3()

geti1()访问i1当前线程中当前存储的值  。

线程可以具有变量的本地副本,并且数据不必与其他线程中保存的数据相同。特别是,另一个线程可能已i1 在其线程中更新,但当前线程中的值可能与该更新值不同。实际上,Java演示了“主”内存的概念,而这是保存变量当前“正确”值的内存。线程可以拥有自己的变量数据副本,并且线程副本可以与“主”内存不同。

geti2() “主”存储器有效地访问i2的值。一个volatile 变量是不允许有一个变量是目前在“主”内存的值不同的本地副本。实际上,volatile声明的变量必须使其数据在所有线程之间同步,这样无论何时在任何线程中访问或更新变量,所有其他线程都会立即看到相同的值。通常,volatile变量具有比“普通”变量更高的访问和更新开销。典型的,允许线程拥有自己的数据副本,这样可以提高效率。

volatile和synchronized之间有两点不同:

首先,synchronized 取并释放监视器上的锁定,这些锁定强制一次只能一个线程执行代码块。这是synchronized一个相当着名的方面。但 synchronized同步内存。实际上,synchronized 将整个线程内存与“主”内存同步。因此,执行geti3()时做了以下操作:

  1. 线程获取对象this的监视器上的锁 。
  2. 线程内存刷新所有变量,即它的所有变量都有效地从“主”内存中读取。
  3. 代码块被执行。在这种情况下,这意味着将返回值设置为当前i3值,该值可能刚刚从“主”存储器复位。
  4. 对变量的任何更改通常都会写入“主”内存,但是对于geti3(),我们没有任何更改。
  5. 线程释放监视器上的对象this锁。

因此,volatile只在线程内存和“主”内存之间同步一个变量的值,synchronized同步线程内存和“主”内存 之间所有变量的值,并锁定和释放监视器以控制多个线程之间的所有权。

从这些信息可以得出结论,synchronized 可能volatile有更多的开销。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值