我有一个多线程应用程序和一个单例类:
public final class Singleton {
private static MyClass mc;
public static final Object getInstance() {
if(mc == null) {
mc = new MyClass();
}
return mc;
}
}
当然,这在一般的多线程场景中不起作用。但请考虑以下情况:
getInstance()
,以便初始化mc。我的假设:
这应该有效,因为mc
字段的初始化和对象的构造发生在所有后续Thread.start()
调用启动其他线程之前。并且线程的Thread.start()
发生在该线程的所有其他操作之前。因此,mc
的初始化发生在所有其他线程中的所有操作之前,以便getInstance()
将为所有线程返回正确的值。
这个假设是对的吗?为什么/为什么不呢?
答案 0 :(得分:5)
你的分析确实很好。
准确地说:在一个线程上发生的所有事情都会在关系之前发生(很明显,就是这样说的:"如果x和y是同一个线程的动作,x在程序顺序中出现在y之前) ,然后是hb(x,y)。")
然后,JLS的17.4.5接着说出以下内容:"在启动线程中的任何操作之前,对线程的start()调用发生。"
因此,在单例实例化和启动的线程之间的顺序之前发生了明显的事情,因此他们可以保证看到最新值。
简单地说:创建的线程可以保证在创建之前看到它的父进程所做的一切,否则并发编程几乎是不可能的。