Spring是否以线程安全的方式发布bean?

我对JVM内部的了解是,如果引用未正确发布,则不同的线程可能会看到相同字段的不同值。

我的问题是: Spring bean容器能保证安全发布吗? 如果没有,我应该使我的所有bean getter和setter synchronized还是使用volatile ? 或者可能使用final字段和构造函数初始化?

我认为这可能只是单例bean的问题,因为原型bean是根据请求线程创建的。 我的理解是否正确?

正如Evgeniy所说,应用程序上下文的初始化发生在一个线程中。 因此,您的问题的答案不是与Spring的内部有关,而是与创建上下文的线程和创建上下文后使用上下文的线程之间的同步细节。

Java内存模型基于先前发生的关系 (Java语言规范,§17.4.5),它由各种规则定义。 例如,在一个线程中调用Thread.start来启动一个新线程发生在新启动的线程本身的所有操作之前 。 因此,如果应用程序的主线程首先创建应用程序上下文,然后启动其他线程进行处理,那么处理线程将保证看到完全初始化的上下文。

标记为volatile字段也强加了一个before-before关系,在某种意义上,如果线程A将一个值写入一个volatile ,那么看到该write的结果的任何其他线程也保证它执行之前看到线程A所做的任何其他操作。易失写。 因此,如果初始化线程和处理线程之间没有任何显式同步,则以下模式足以确保安全性

 public class Setup { private volatile boolean inited = false; private ApplicationContext ctx; public boolean isInited() { return inited; } public ApplicationContext getContext() { return ctx; } public void init() { ctx = new ClassPathXmlApplicationContext("context.xml"); inited = true; // volatile write } } public class Processor { private void ensureInit() { while(!setup.isInited()) { // volatile read Thread.sleep(1000); } } public void doStuff() { ensureInit(); // at this point we know the context is fully initialized } }