我正在尝试编写一个实例方法来懒惰地初始化几个静态变量。我初始化的对象是不可变的,并且对象的引用不会被类中的任何其他实例或静态方法更改。我希望初始化代码永远不会被执行多次,即使在许多不同的线程中可能有多个类的实例。初始化需要在实例方法中进行,因为该方法会覆盖超类中的方法。我使用的方法如下。
private static volatile boolean isPrepared;
private static volatile Object object1;
private static volatile Object object2;
private static volatile Object object3;
@Override
void prepare() {
synchronized (this.getClass()) {
if (isPrepared) { return; }
object1 = expensiveCalculation1();
object2 = expensiveCalculation2();
object3 = expensiveCalculation3();
isPrepared = true;
}
}
我假设由于初始化发生在一个同步的块中,因此实例不可能将isPrepared
视为true
,除非object1
,{{1 }和object2
都是非空的。我也假设它只是将object3
声明为prepare()
,因为锁只是synchronized
而无法工作。我的假设是对的吗?另外,当你想将它们视为一起初始化时,将几个变量标记为this
是一个好主意,还是应该将它们捆绑在一起成为一个不可变类?
答案 0 :(得分:1)
将所有延迟初始化状态捆绑为不可变对象通常是首选方法,因为您需要的所有是volatile
变量,没有同步。如果另一个线程在初始化过程中开始初始化,那么这种安排会让你有一些重复的努力,但是可以最小化它的可能性,例如通过将一个标记值写入volatile
来发出信号" in进展"州。
答案 1 :(得分:0)
您可以使用下一种方法:https://stackoverflow.com/a/11879164/2413618 将变量放入静态嵌套类中。当第一次访问嵌套类时,将初始化所有变量。