Что касается шаблона Singleton в Java, вместо назначения статической переменной новой локальной переменной в методе, почему бы не использовать непосредственно статическую переменную? - PullRequest
0 голосов
/ 29 мая 2018

Я не понял, для чего предназначен код => Экземпляр DataProvider = sInstance; в приведенном ниже методе.Кто-нибудь, помогите мне объяснить подробно?Почему бы не использовать непосредственно sInstance?

private static volatile DataProvider sInstance = null;
 public static DataProvider getInstance() {
     DataProvider instance = sInstance;
      if (instance == null) {
          synchronized (DataProvider.class) {
              instance = sInstance;
              if (instance == null) {
                  instance = sInstance = new DataProvider();
              }
          }
      }
      return instance;
  }

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

Согласно книге Джошуа Блоха Prentice.Hall.Effective.Java.2nd.Edition.May.2008,

В частности, необходимость результата локальной переменной может быть неясной.Эта переменная гарантирует, что поле будет прочитано только один раз в общем случае, когда оно уже инициализировано.Хотя это и не является строго необходимым, это может повысить производительность и стать более элегантным с помощью стандартов, применяемых к низкоуровневому параллельному программированию.На моей машине описанный выше метод примерно на 25 процентов быстрее, чем очевидная версия без локальной переменной.

0 голосов
/ 01 июня 2018

Основная причина - Волатильность.Как ответ @Hien Nguyen, это улучшает производительность на 25%.Причина. Volatile всегда получает данные из основной памяти, а не из кеша, поэтому это слишком медленно.Объявите instance = sInstance, чтобы избежать многократного чтения данных из основной памяти (медленно).Мы трижды читаем данные из sInstance, если не используем временную переменную, поэтому мы используем временную переменную, что ухудшит производительность.

См. Этот раздел, чтобы понять, почему доступ к Volatile медленен: Почему доступпеременная volatile примерно на 100 медленнее, чем член?

Ваш ответ может быть таким же, как в этом разделе: Java: использование локальной переменной в двойной проверке идиома

0 голосов
/ 29 мая 2018

Используется в качестве отложенной инициализации (например, создание экземпляра синглтона возможно только при необходимости).Проблема с этим кодом в том, что он сломан.Очевидно, что даже при использовании блока синхронизации существует вероятность того, что что-то пойдет не так (из-за условий гонки).Поэтому не используйте этот метод, если вы хотите быть в безопасности!

Альтернативы: Использование прямого присваивания (как вы sugessted);

private static volatile DataProvider sInstance = new DataProvider();

Или использование enum (как предложено @MadProgrammer);

public enum DataProvider
{

    INSTANCE;

    // singleton content
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...