Это классическая проблема, которая называется проблема двойной проверки блокировки .
Проблема в том, что у вас условие гонки , потому что вы проверяете, является ли instance
значение null
и присваиваете значение. Одно из решений этой проблемы, которое мне нравится в Java:
public class LazyInitRace {
private static class Container {
public final static ExpensiveObject INSTANCE = new ExpensiveObject();
}
public ExpensiveObject getInstance() {
return Container.INSTANCE;
}
}
Способ, которым это работает, заключается в том, что внутренний класс не инициализируется до тех пор, пока на него не ссылаются (что приводит к ленивой загрузке), а загрузка класса является атомарной и поточно-безопасной операцией.
Однако существуют и другие действительные решения.