当前位置: 首页 > 知识库问答 >
问题:

Java volatile读取刷新写入,以及volatile写入更新读取吗

空正豪
2023-03-14

我理解读-获取(在它之后不进行后续读/写操作的重新排序)和写-释放(在它之前不进行读/写操作的重新排序)。我的q是:-

  1. 在读获取的情况下,它前面的写操作会被刷新吗

另外,在Java中,读获取和volatile读相同,写释放和volatile写相同吗?

为什么这很重要,让我们以写发布为例...

y = x; // a read.. let's say x is 1 at this point
System.out.println(y);// 1 printed
//or you can also consider System.out.println(x);
write_release_barrier();
//somewhere here, some thread sets x = 2
ready = true;// this is volatile
System.out.println(y);// or maybe, println(x).. what will be printed?

在这一点上,x是2还是1?这里,考虑准备好成为挥发性的。我知道挥发性之前的所有商店都将首先可见...然后只有挥发性才会可见。谢谢。

参考:-http://preshing.com/20120913/acquire-and-release-semantics/

共有3个答案

景理
2023-03-14

不,读取易失性变量不会刷新之前的写入。可见操作将确保之前的操作可见,但读取易失性变量对其他线程不可见。

不,写入易失性变量不会清除缓存中以前读取的值。它只保证刷新以前的写入。

在您的示例中,很明显y在最后一行仍然是1。根据前面的输出,只对y进行了一次赋值,那就是1。也许这是一个打字错误,您的意思是写println(x),但是即使这样,2的值也不能保证是可见的。

蒯硕
2023-03-14

Java内存模型没有按照“读取获取”和“写入释放”来指定。这些术语/概念来自其他语境,正如你所引用的文章非常清楚地表明的那样,它们经常被(不同的专家)用来表示不同的东西。

如果你想理解挥发物在Java中是如何工作的,你需要理解Java记忆模型和Java术语...(幸运的是)有充分的依据,并且精确地指定了1。试图将Java记忆模型映射到“读取-获取”和“写入-释放”语义学是一个坏主意,因为:

>

假设的JMM-

1-...专家们注意到JMM的一些版本存在缺陷。但关键是,已经认真尝试提供理论上合理的规范...作为Java语言规范的一部分。

汲永嘉
2023-03-14

否:不是所有写入都被刷新,也不是所有读取都被更新。

Java在多线程的“之前发生”基础上工作。基本上,如果A发生在B之前,B发生在C之前,那么A发生在C之前。所以你的问题相当于x=2是否正式发生在某个读x的动作之前。

在边缘基本上通过与JLS 17.4.4中定义的关系同步而建立之前发生。有几种不同的方法可以做到这一点,但对于volatile,它基本上相当于在读取同一volatile之前对volatile进行写入:

  • 对易失性变量v(§8.3.1.4)的写入与任何线程对v的所有后续读取同步(其中“后续”根据同步顺序定义)。

有鉴于此,如果线程写入ready=true,那么单独写入并不意味着在它之前发生任何事情(就写入而言)。事实恰恰相反;如果它们读取ready,那么写入ready的操作将先于其他线程上的操作。

因此,如果另一个线程(设置x=2)在设置x=2后已写入ready,而这个线程(您在上面发布的)则读取ready,那么它将看到x=2。这是因为写入发生在读取之前,因此读取线程可以看到写入线程所做的一切(包括写入)。否则,你就有了一场数据竞赛,基本上所有的赌注都输掉了。

还有几点需要注意:

  • 如果你没有“发生在之前”的边缘,你仍然可以看到更新;只是你不能保证。所以,不要假设如果你没有读到write toready,那么你仍然会看到x=1。您可能会看到x=1或x=2,或者可能会看到其他写入(包括默认值x=0)
 类似资料:
  • null 如果我的理解有误,请指正。还有以下问题: 我的理解是,Hadoop中的文件读/写没有任何并行性,它所能执行的最佳操作与传统的文件读或写(即,如果复制设置为1)+分布式通信机制中涉及的一些开销是一样的。 并行性仅在数据处理阶段通过Map Reduce提供,而不是在客户端读/写文件期间提供。

  • 问题内容: 我正在编写一个连接到servlet的程序,这要感谢a,但是我在检查url时卡住了 我得到了错误: java.net.ProtocolException:读取输入后无法写入输出。 如果我用注释中的代码检查网址,但不幸的是它可以正常工作,我需要检查网址,所以我认为问题出在方法上,但我不知道如何解决 非常感谢你 问题答案: HTTP协议基于请求-响应模式:首先发送请求,然后服务器响应。服务器

  • 问题内容: 我试图逐行读取文件,然后使用Node.js将其输出到另一个文件。 我的问题是由于Node.js的异步特性,行的顺序有时会混乱。 例如,我的输入文件就像:第1行第2行第3行 但是输出文件可能像:第1行第3行第2行 下面是我的代码。 任何想法将不胜感激,谢谢。 问题答案: 如果要编写同步代码,请仅使用同步功能: 对于异步方法,您可以编写类似

  • 如何写这个问题?老实说,我不明白这个问题的意思。A) 编写读者和作者优先于读者的解决方案,并评论每个信号量的功能。(记住变量和信号量的定义和初始化)B)读卡器的优先级意味着什么?当一个作家在写作时,到达的读者会发生什么?当编写器结束其操作时会发生什么?

  • 是否可以同时从套接字读取和写入?我有一个连续读取套接字的线程。由于只有一个线程从套接字读取,因此读取操作是线程安全的。现在我有很多线程(比如 100 个)写入套接字。因此,很明显,我必须通过做这样的事情来使写入操作线程安全, 现在我有一个线程不断调用readMessage()函数(在while循环中)。据我所知,如果套接字上没有要读取的消息,语句< code > inputstream . rea

  • 问题内容: 我有一个数据结构,我希望能够在关闭程序之前写入文件,然后在下次应用程序启动时从文件中读取数据以重新填充该结构。 我的结构是。对象很简单;对于成员变量,它具有一个String和两个布尔类型的小型本机数组。这是一个真正简单的应用程序,我希望一次不会超过10-15 对。 我一直在尝试(不成功)对象输入/输出流。我需要使对象类可序列化吗? 您能给我一些最好的建议吗?我只需要向正确的方向推进即可