Частично построенные объекты в не поточнобезопасном синглтоне - PullRequest
5 голосов
/ 19 октября 2010

В многопоточной среде как поток может увидеть «частично сконструированный объект»?Я понял, что это не потокобезопасно, так как несколько потоков могут создавать несколько экземпляров.

class LazyInit
{  private static Resource resource = null;

    public static getInstance()
    {  if (resource == null) { resource = new Resource();  }
       return instance;
    }
}

1 Ответ

7 голосов
/ 19 октября 2010

Из-за неправильной записи.

Если ваш конструктор пишет в неконечные члены, они не должны быть зафиксированы в памяти сразу, и на самом деле они могут даже быть зафиксированы после переменной singleton. Java гарантирует, что поток, который влияет, видит последовательности по порядку, но не так, как другие потоки, если вы не установите барьер памяти.
См. этот вопрос и эту страницу спецификации Java для получения дополнительной информации.

Возможно, это не относится к делу, но в вашем примере вполне возможно, что два потока видят разные синглтоны. Предположим, что один поток проверяет недействительность переменной, вводит if и получает прерывание, прежде чем он получает возможность построить объект. Новый поток, который получает ЦП, теперь тестирует объект с еще нулевым значением, создает синглтон. Когда старый поток снова запустится, он успешно завершит создание объекта и перезапишет переменную singleton.
Другая, более пугающая проблема возникает, если конструктор Resource вызывает метод, который в конечном итоге приведет к другому вызову этого getInstance. Даже если состояние программы не приводит к бесконечному циклу, вы создадите несколько одноэлементных экземпляров.

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