2

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

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

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

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

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

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

4

2 回答 2

2

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

在没有发生之前的关系的情况下在线程之间传递对象的罕见情况称为不安全发布。围绕使用final字段的规则允许这样做是安全的。但是,您很少会发现自己想要依赖它。

在线程上调用和线程的执行之间总是存在发生前的关系。start所以如果一个对象在启动前被安全地发布到启动线程,启动的线程也会连贯地看到该对象。

于 2009-11-05T21:47:37.827 回答
0

标记变量'volatile'不会阻止线程看到'脏'值吗?

于 2009-11-05T22:36:28.517 回答