首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java中易失性和同步性的区别

Java中易失性和同步性的区别
EN

Stack Overflow用户
提问于 2017-12-27 01:43:33
回答 3查看 0关注 0票数 0

我想知道声明变量为volatile并始终访问synchronized(this)块在Java中(特别是J2ME)?

根据这篇文章http://www.javamex.com/tutorials/同步[医]挥发物.shtml有很多要说的,有许多不同之处,但也有一些相似之处。

我对这段信息特别感兴趣:

...

  • 对易失性变量的访问从来没有阻止的潜力:我们只做简单的读或写,所以与同步块不同的是,我们永远不会持有任何锁;
  • 因为访问易失变量从来不持有锁,所以它不适合于我们想要访问的情况。读-更新-写作为原子操作(除非我们准备“错过更新”);

他们说的是什么意思读-更新-写是吗?不是写也是更新,还是它们仅仅意味着更新写的内容取决于阅读的信息吗?

最重要的是,什么时候声明变量更合适?volatile而不是通过synchronized是吗?使用它是个好主意吗?volatile对于依赖于输入的变量?例如,有一个名为render它是通过呈现循环读取并由按键事件设置的吗?

EN

回答 3

Stack Overflow用户

发布于 2017-12-27 09:23:05

易失性场改性剂同步修改码块方法,我们可以使用这两个关键字指定简单访问器的三个变体:int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;}geti1()访问当前存储在i1在当前线程中。线程可以拥有变量的本地副本,并且数据不必与其他线程中持有的数据相同。特别是,另一个线程可能已经更新了i1在它的线程中,但是当前线程中的值可能与更新后的值不同。实际上,Java有一个“主”内存的概念,而这是保存变量当前“正确”值的内存。线程可以为变量拥有自己的数据副本,并且线程副本可以与“主”内存不同。因此,实际上,“主”内存有可能具有i1,线程1的值为i1而为了thread2有价值i1如果thread1andthread2都更新了i1,但这些更新的值尚未传播到“主”内存或其他线程。 另一方面,geti2()有效地访问i2从“主”记忆。不允许可变变量具有与当前保存在“主”内存中的值不同的变量的本地副本。实际上,声明为易失性的变量必须在所有线程之间同步其数据,以便每当您访问或更新任何线程中的变量时,所有其他线程都会立即看到相同的值。通常,易失性变量比“普通”变量具有更高的访问和更新开销。一般来说,线程可以拥有自己的数据副本,以提高效率。 排球和同步有两个不同之处。 首先,同步获取并释放监视器上的锁,每次只能强制一个线程执行代码块。这是众所周知的同步方面。但是同步也会同步内存。实际上,同步将整个线程内存与“主”内存同步。所以执行geti3()是否有下列情况:

  1. 线程获取监视器上的锁,以便实现这个对象。
  2. 线程内存刷新其所有变量,即从“主”内存中有效读取其所有变量。
  3. 执行代码块(在本例中,将返回值设置为当前的i3值,该值可能刚刚从“主”内存中重置)。
  4. (对变量的任何更改现在通常都会写入“主”内存,但对于geti 3(),我们没有任何更改。)
  5. 线程将释放监视器上的锁,以便实现此对象。

因此,如果VERIAR只同步线程内存和“Main”内存之间的一个变量的值,则同步线程内存和“Main”内存之间的所有变量的值,并锁定和释放一个监视器来启动。显然,同步的开销可能比易失性要大。

http://javaexp.blogpot.com/2007/12/差异-易失性-和.html

票数 0
EN

Stack Overflow用户

发布于 2017-12-27 10:28:15

synchronized是方法级/块级访问限制修饰符。它将确保一个线程拥有关键部分的锁。只有拥有锁的线程才能进入synchronized封锁。如果其他线程试图访问此关键部分,则必须等待当前所有者释放锁。

volatile变量访问修饰符,它强制所有线程从主内存中获取变量的最新值。访问不需要锁定。volatile变量。所有线程都可以同时访问可变值。

使用易失性变量的一个很好的例子:Date变量。

假设您已经使日期变量volatile所有访问此变量的线程总是从主内存中获取最新数据,以便所有线程都显示真实(实际)日期值。您不需要不同的线程显示相同变量的不同时间。所有线程都应该显示正确的日期值。

[图片]
[图片]

看看这个文章为了更好地理解volatile概念。

劳伦斯·多尔·克利里解释说read-write-update query...

关于您的其他查询

什么时候声明可变变量比通过同步访问变量更合适?

你必须用volatile如果您认为所有线程都应该实时获得变量的实际值,就像我为Date变量解释的示例一样。

对于依赖于输入的变量,使用挥发性是个好主意吗?

答案将与第一次查询相同。

请参阅此文章为了更好的理解。

票数 0
EN

Stack Overflow用户

发布于 2017-12-27 11:28:57

  1. volatile关键字在java中是一个字段修饰符,而synchronized修改代码块和方法。
  2. synchronized获取并释放对监视器的java的锁volatile关键字不需要这个。
  3. Java中的线程可以被阻塞以等待任何监视器synchronized,情况并非如此volatile关键字在Java中。
  4. synchronized方法对性能的影响大于volatile关键字在Java中。
  5. volatile关键字在Java中只同步线程内存和“主”内存之间的一个变量的值synchronized关键字同步线程内存和“主”内存之间的所有变量的值,并锁定和释放监视器以引导。因为这个原因,synchronized关键字在Java中的开销可能比volatile...
  6. 不能在空对象上同步,但是volatilejava中的变量可能为NULL。
  7. 从Java 5编写到volatile字段具有与监视器释放相同的内存效果,从易失性字段读取的内存效果与监视器获得的内存效果相同。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100003161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档