关键字volatile和synchronized之间的差异

时间:2014-06-24 13:42:18

标签: java

在哪种情况下volatile可以替换synchronized?在将它们声明为volatile之后,double和long上的写操作怎么会变成原子

2 个答案:

答案 0 :(得分:0)

java中的volatile和synchronized之间的区别

  • synchronized修改代码块和方法,其中包含volatile keyword用作带变量的修饰符。

  • 在Java中,volatile关键字仅同步一个变量的值 同步关键字时线程内存和主内存之间的关系 同步线程内存和main之间的所有变量的值 存储器

  • 与同步相比,volatile的工作速度更快,因为已同步 由于获得和释放锁定而对性能产生很大影响。

  • volatile不需要获取和释放锁定,但它是 同步所必需的。

difference-between-volatile-and- synchronize阅读一篇非常好的文章。

为了清楚起见,在此解释相同 -

      int i1;              int geti1() {return i1;}
volatile int i2;              int geti2() {return i2;}
        int i3; synchronized int geti3() {return i3;}

geti1()访问当前线程中当前存储在i1中的值。线程可以具有变量的本地副本,并且数据不必与其他线程中保存的数据相同。特别是,另一个线程可能已在其线程中更新了i1,但当前线程中的值可能与该更新值不同。事实上,Java有一个" main"内存,这是保存当前"纠正"变量的值。线程可以拥有自己的变量数据副本,并且线程副本可以与" main"记忆。所以事实上," main"内存为i1的值为1,如果thread1和thread2都更新了i1,则thread1的值为i1,而thread2的值为i1,但这些更新的值尚未传播到& #34;主"记忆或其他线程。

另一方面, geti2()有效地从" main"中访问i2的值。记忆。不允许volatile变量具有与" main"中当前保存的值不同的变量的本地副本。记忆。实际上,声明为volatile的变量必须使其数据在所有线程之间同步,因此无论何时在任何线程中访问或更新变量,所有其他线程都会立即看到相同的值。通常,volatile变量具有比" plain"更高的访问和更新开销。变量。通常,允许线程拥有自己的数据副本以提高效率。

执行 geti3()执行以下操作:

  • 线程获取监视器上的对象锁定。
  • 线程内存刷新所有变量,即它具有所有变量 变量有效地从" main"记忆。
  • 执行代码块(在这种情况下将返回值设置为 i3的当前值,可能刚刚从" main" 存储器)。
  • (对变量的任何更改通常都会写入" main" 内存,但对于geti3(),我们没有任何变化。)
  • 线程释放监视器上的锁定对象。

所以volatile只在线程内存和" main"之间同步一个变量的值。 memory,synchronized同步线程内存和" main"之间所有变量的值。内存,锁定并释放要启动的监视器。明确同步可能比易失性更具开销。

答案 1 :(得分:-2)

<强>无!

主要是volatile用于变量,synchronized用于方法/块。

Volatile关键字用于确保多线程环境中线程的可见性。如果变量不是易失性的,则两个不同的线程可能具有两个不同的本地副本。使其变为volatile,确保所有线程都反映出相同的值。

synchronized用于方法/块。这些方法或块是关键区域,其监视器在访问之前需要锁定。每个对象都有一个关联的监视器只要线程持有监视器,其他线程就不能访问由该监视器控制的关键区域。