【发布时间】:2017-11-05 13:03:02
【问题描述】:
似乎在启动应用程序期间发生了死锁。
我有 jstack 文件,在其中我发现一个线程调用 TariffModelManager.
public class TariffModelManager{
...
private static final TariffModelManager tariffModelManager = TariffModelManager.getInstance();
...
private static volatile TariffModelManager _instance;
private TariffModelManager(){}
public static TariffModelManager getInstance() {
if(_instance == null) {
synchronized(TariffModelManager.class) {
if(_instance == null) _instance = new TariffModelManager();
}
}
return _instance;
}
...
}
我认为,通过调用 getInstance() 方法来初始化静态字段显然是错误的,在该方法中检查了另一个字段 (_instance),代码中描述如下,但到底发生了什么?
- 类初始化时,静态字段从上到下初始化;
- 我们正在尝试初始化“tariffModelManager”字段...
- 调用方法getInstance(),检查_instance字段(但它没有初始化!);
- 那么我们必须执行这个类的构造函数;
- 如果 _instance 字段已经在构造函数中初始化,是否可以在静态字段初始化序列中设置为 null?
我的问题不是如何解决这个问题,而是描述这段代码执行时到底发生了什么!
更新: Here我找到了详细的类初始化过程,但仍然不清楚“tariffModelManager”和“_instance”字段的初始化顺序。
谢谢!
【问题讨论】:
-
似乎对我有用。当我添加一个打印
TariffModelManager.getInstance()的主要方法时,它就是这样做的。 -
是的,我也测试过,但不是在并发环境中。正如我上面所说,在并发环境中使用此代码的应用程序存在问题,我认为这就是原因。
-
1.在类初始化之前,没有人可以调用
getInstance()方法,并且存在针对多个并发初始化的同步障碍。 2. 正如你自己所说,静态字段是从头到尾初始化的。
标签: java