Подтвердить что ты не робот

Шаблон Singleton - связано ли раннее связывание (со связанными статическими переменными) с необходимостью блокировки мьютексов?

Говорят, что раннее связывание решает проблему синхронизации. Я не мог понять "как". Это что-то особенное для Java или то же самое относится и к С++?

поэтому, с помощью этого метода мы фактически не будем требовать блокировку мьютекса?

enter image description here

4b9b3361

Ответ 1

Я думаю, что они ссылаются на создание экземпляра Singleton перед запуском/созданием любых потоков, что облегчает необходимость синхронизации при создании.

EDIT: добавление информации о С++ и статических переменных

В С++ статические переменные также инициализируются перед выполнением, как упоминает Дэвид Харкнесс для Java. Одна из проблем с этим в С++ может быть во встроенных средах, где вызовы malloc/new can not выполняются до тех пор, пока система не будет инициализирована, и в этом случае использование статического инициализатора Singleton может быть проблематичным.

Ответ 2

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

Ответ 3

Ответ YES!. с помощью этого метода вам не понадобится блокировка для "получения экземпляра"
--Edit--
причина в том, что создание объекта является частью процесса загрузки операционной системой, которая гарантирует ее загрузку до запуска вашего кода.
Постскриптум он будет применяться и к С++.
примечания:
1. вам не понадобится блокировка для "экземпляра экземпляра", но вам может понадобиться, если есть общие члены экземпляра.
2. это возможно только в том случае, если вам не нужны параметры для инициализации экземпляра.

Ответ 4

Одна из вещей, которую пыталась решить ленивая инстанция (не только связанная с С++), - это статический идентификатор порядка инициализации. Это проблема в том, что у вас мало контроля над порядком инициализации (с несколькими единицами перевода), но для зависимостей может потребоваться, чтобы объект уже существовал до того, как другой может быть создан. При ленивой инстанцировании объект создается по мере необходимости, поэтому, если нет круговой зависимости, вы должны быть в порядке.

Если вам нужны проблемы с зависимостями, и вы все равно хотите избежать затрат на блокировку для каждого getInstance(), вы все равно можете получить желаемое создание, инициализировав все свои синглеты перед началом потоков, добавив функцию Initialize() к вашему классы. Таким образом, вы можете проверить с утверждениями, что синглтоны инициализируются только один раз и доступны только после их инициализации.

Заметим, что:

  • общие ресурсы должны по-прежнему блокироваться при доступе к ним.
  • из С++ 11 on (и при использовании gcc, поскольку я не уверен в других компиляторах), самым простым решением является использование статической функциональной переменной в getInstance и возврат ссылки на эту переменную. Это безопасно для потоков.

    class Example
    {
      ...
      static Example& getInstance()
      {
        static Example instance;
        return instance;
      }
    };
    

Ответ 5

Если вы хотите, чтобы член singelton оставался пустым до первого вызова, вы можете синхронизировать только создание. например

getInstance() {
     if (singleton == null) {
         lock();
         if (singleton == null) {
               singleton = new Singleton();
         }
         unlock();
     }
     return singleton;
}