При этом используется блокировка с двойной проверкой, обратите внимание, что if(uniqueInstance == null)
не находится внутри синхронизированной части.
Если uniqueInstance
не является энергозависимым, он может быть "инициализирован" с частично созданным объектом, где деталиэтого не видно никому, кроме потока, выполняющегося в блоке synchronized
.volatile делает в этом случае операцию «все или ничего».
Если у вас не было синхронизированного блока, вы можете получить 2 потока, одновременно попадающих в эту точку.
if(uniqueInstance == null) {
uniqueInstance = new someClass(); <---- here
И вы создаете 2 объекта SomeClass, которые побеждают цель.
Строго говоря, вам не нужен volatile, метод мог бы быть
public static someClass getInstance() {
synchronized(FullDictionary.class) {
if(uniqueInstance == null) {
uniqueInstance = new someClass();
}
return uniqueInstance;
}
}
Но это вызывает синхронизациюи сериализация каждого потока, который выполняет getInstance ().