gpt4 book ai didi

java - 由于内存不一致,线程能否观察到对象中的垃圾值?

转载 作者:行者123 更新时间:2023-11-30 09:57:31 25 4
gpt4 key购买 nike

经过大量研究后,我相信我对 JMM 非常了解,当然足够了解当一个对象在两个线程之间共享时,您必须同步同一监视器上的所有访问。我知道,如果多个 Activity 线程同时访问一个对象,那么关于它们将观察到什么的所有赌注都会落空。

但是,如果一个对象是在使用它的某个其他线程启动(或该线程甚至被构造)之前确定性地实际构造的,那么 JMM 是否保证后面的线程看到的对象的内容与由较早的设置线程配置。

IOW,是否有可能在线程中第一次引用一个对象并观察到脏内存,例如,由于CPU缓存,而不是对象的真实内容?或者 JMM 是否保证在首次获取对任何给定对象的引用时,它引用的内存是一致的?

我问是因为我在很多地方使用了一种特定模式,但我仍然不确定。我经常有一个对象,它以零碎的方式构建和配置,然后不可变地使用。因为它是零碎配置的,所以它的成员都不能是最终的(除非必须,否则我不想将它们全部更改为构建器模式)。

例如,创建一个 HTTP 连接处理程序,并添加插件对象来处理特定的 HTTP 请求。处理程序是使用修改器创建和配置的,然后安装到使用线程池处理连接的 TCP 连接处理器中。由于连接处理程序是在连接处理器的线程池启动之前配置和安装的,并且一旦安装到连接处理器中就永远不会更改,所以我不在设置所有内容的线程和处理连接的线程之间使用显式同步。

在这种特定情况下,线程配置可能也是启动线程池的同一个线程,并且由于线程池启动是同步的,因此用完它的所有线程也在同一个线程池对象上同步,所以这可能会掩盖任何潜在的问题(我的 API 不要求起始线程与配置线程相同)。

最佳答案

通常,当线程交互时,您应该具有happens-before 关系。例如,由并发队列提供。不一定需要更精细的同步。

在没有happens-before 关系的线程之间传递对象的罕见情况被称为不安全发布。围绕 final 字段的使用有一些规则可以确保安全。但是,您应该很少会发现自己想要依赖它。

在线程上调用 start 与线程执行之间始终存在happens-before 关系。因此,如果一个对象在启动前安全地发布到启动线程,则启动线程也会连贯地看到该对象。

关于java - 由于内存不一致,线程能否观察到对象中的垃圾值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1683610/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com