Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Синхронизация синглтона, почему синхронизируется Class? 
V
    Опции темы
check
Дата 23.12.2010, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 610
Регистрация: 3.4.2006

Репутация: 2
Всего: 23



Вот такой вариант синхронизации синглтона:
Код

public static SingletonImpl getInstance(){
    if (self == null){
        synchronized(SingletonImpl.class){
            if (self == null){
                self = new SingletonImpl();
            }
        }
    }
    return self;
}

Мне не совсем понятно: почему в synchronized-блок передаётся объект класса Class?  Мне казалось, что передавать туда нужно инстанс класса, в данном случае - переменную self.

Это сообщение отредактировал(а) check - 23.12.2010, 15:30
PM MAIL   Вверх
MisterCleric
Дата 23.12.2010, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 5
Всего: 38



Привет
У тебя же метод getInstance() static. И он пренаждлежит классу, а не инстансу


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
jk1
Дата 23.12.2010, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

Мне казалось, что передавать туда нужно инстанс класса, в данном случае - переменную self.


self к этому моменту равен null, на нем синхронизироваться не стоит.
На объекте инстанса обычно синхронизируются в методах инстанса. А тут static метод, он относится к классу, а не к объекту. 


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Nofate
Дата 23.12.2010, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 266
Регистрация: 13.10.2008

Репутация: 4
Всего: 8



по-вашему бы получилось

Код

 if (self == null){
        synchronized(self){
        }
}


то есть заведомо зная, что self не присвоен, мы все равно пихаем его в synchronized )
вся загвоздка в том, что метод статический и экземпляра еще никакого нет. поэтому используется объект класса Class


--------------------
The future is not set, there is no fate but what we make for ourselves.
Нофейтово пространство и смежные области 
PM MAIL WWW ICQ   Вверх
check
Дата 23.12.2010, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 610
Регистрация: 3.4.2006

Репутация: 2
Всего: 23



Цитата(MisterCleric @  23.12.2010,  15:37 Найти цитируемый пост)
У тебя же метод getInstance() static. И он пренаждлежит классу, а не инстансу 
Упс, да... Действительно.  Теперь ясно.



Цитата(Nofate @  23.12.2010,  15:42 Найти цитируемый пост)
по-вашему бы получилось

Код

if (self == null){
        synchronized(self){
        }
}



то есть заведомо зная, что self не присвоен, мы все равно пихаем его в synchronized )

Ну, я бы не стал, конечно, помещать synchronized внутрь if. Проверка на null была бы внутри synchronized-блока.

PM MAIL   Вверх
jk1
Дата 23.12.2010, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

Ну, я бы не стал, конечно, помещать synchronized внутрь if. Проверка на null была бы внутри synchronized-блока.


Двойная проверка в примере делается не зря: внешняя - позволяет избегать синхронизации когда instance уже создан, внутренняя - позволяет избежать возможности создания двух и более экземпляров синглетона в многопоточном окружении.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
_sten_
Дата 23.12.2010, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 184
Регистрация: 29.9.2006

Репутация: нет
Всего: 3



если синхронизироватся по null то свалится NullPointerException, тоесть код типа:
Цитата

Код

synchronized(self){
if (self == null){
...
}
}



смысла не имеет.

синхронизироватся можно по любому общему обьекту, вариант типа:
Код

private static final Object monitor = new Object();
public static SingletonImpl getInstance(){
    if (self == null){
        synchronized(monitor){
            if (self == null){
                self = new SingletonImpl();
            }
        }
    }
    return self;
}

тоже работать будет. Но что бы не плодить лишних обьектов удобно использовать SingletonImpl.class

кста этот дабл чек для синголтона нитакой уж и сикьюрный, и может породить проблемы. подробнее сдесь
--------------------
WARNING: Condition 'to_be || !to_be' is always 'true' !
PM MAIL ICQ   Вверх
jk1
Дата 23.12.2010, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



_sten_, 

Это все конечно правильно, но только для старой модели памяти в Java, допускавшей более свободное переупорядочивание операторов при компиляции. В Wiki кстати дальше об этом тоже написано:

Цитата

As of J2SE 5.0, this problem has been fixed. The volatile keyword now ensures that multiple threads handle the singleton instance correctly.


Таким образом, добавив volatile к переменной, мы эту дыру закрываем.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Старовъръ
Дата 23.12.2010, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 4
Всего: 10



Что починили - так это volatile, оно зароботало как надо, однако все одно подход менее правильный (менее быстрый и элегантный), нежели подход Билла Пью с внутренним холдером или подход Джошуа Блоха с перечисляемым типом. Подробней читайте здесь. 
На вашем месте я бы трижды подумал, прежде чем применять ленивую загрузку - если можно без нее, - лучше без нее.

Это сообщение отредактировал(а) Старовъръ - 23.12.2010, 21:57
PM MAIL WWW   Вверх
mbasil
Дата 27.12.2010, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 399
Регистрация: 4.5.2007
Где: Москва

Репутация: 2
Всего: 13



Кстати Хорстман в своей  книге пишет, что volatile срабатывает не на всех VM. Так что стоит ли на него полагаться?
PM MAIL   Вверх
Старовъръ
Дата 27.12.2010, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.5.2008

Репутация: 4
Всего: 10



Начиная с Java 5 volatile везде работает одинаково.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0540 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.